লারাভেলের অনুমতিগুলির জন্য ফিল্টার করার সময় পারফরম্যান্সের জন্য সর্বোত্তম পদ্ধতির


9

আমি এমন একটি অ্যাপ্লিকেশনটিতে কাজ করছি যেখানে ব্যবহারকারীর বিভিন্ন বিভিন্ন পরিস্থিতিতে বিভিন্ন ফর্মের অ্যাক্সেস পেতে পারে। ব্যবহারকারীর কাছে ফর্মের সূচক ফেরত দেওয়ার সময় আমি সর্বোত্তম পারফরম্যান্সের সাথে পদ্ধতির তৈরি করার চেষ্টা করছি।

নিম্নলিখিত পরিস্থিতিগুলির মাধ্যমে কোনও ব্যবহারকারীর ফর্মগুলিতে অ্যাক্সেস থাকতে পারে:

  • নিজস্ব ফর্ম
  • দল ফর্মের মালিক
  • একটি ফর্মের মালিক এমন একটি গোষ্ঠীর অনুমতি রয়েছে
  • একটি ফর্মের মালিক এমন একটি দলের কাছে অনুমতি রয়েছে s
  • একটি ফর্ম অনুমতি আছে

আপনি দেখতে পাচ্ছেন যে 5 টি সম্ভাব্য উপায় রয়েছে যা ব্যবহারকারী কোনও ফর্ম অ্যাক্সেস করতে পারে। আমার সমস্যাটি হল আমি কীভাবে ব্যবহারকারীর কাছে অ্যাক্সেসযোগ্য ফর্মগুলির একটি অ্যারে সর্বাধিক দক্ষতার সাথে ফিরিয়ে আনব।

ফর্ম নীতি:

আমি মডেল থেকে সমস্ত ফর্ম পেতে এবং তারপরে ফর্ম নীতি দ্বারা ফর্ম ফিল্টার করার চেষ্টা করেছি। প্রতিটি ফিল্টার পুনরাবৃত্তির হিসাবে এটি নীচে প্রদর্শিত হিসাবে 5 বার একটি অন্তর্ভুক্ত () স্বতঃস্ফূর্ত পদ্ধতিতে ফর্মটি পাস করার পরে এটি একটি পারফরম্যান্স সমস্যা বলে মনে হচ্ছে। ডাটাবেসে আরও ফর্মগুলির অর্থ এটি ধীর হয়ে যায়।

FormController@index

public function index(Request $request)
{
   $forms = Form::all()
      ->filter(function($form) use ($request) {
         return $request->user()->can('view',$form);
   });
}
FormPolicy@view

public function view(User $user, Form $form)
{
   return $user->forms->contains($form) ||
      $user->team->forms->contains($form) ||
      $user->permissible->groups->forms($contains);
}

যদিও উপরের পদ্ধতিটি এটি কার্য সম্পাদন করে বোতল ঘাড়।

আমি যেগুলি দেখতে পাচ্ছি সেগুলি থেকে আমার নিম্নলিখিত বিকল্পগুলি হ'ল:

  • ফর্মপলিসি ফিল্টার (বর্তমান পদ্ধতির)
  • সমস্ত অনুমতি জিজ্ঞাসা (5) এবং একক সংগ্রহের মধ্যে একীভূত
  • সমস্ত অনুমতি (5) এর জন্য সমস্ত সনাক্তকারীকে জিজ্ঞাসা করুন, তারপরে একটি IN () বিবৃতিতে সনাক্তকারী ব্যবহার করে ফর্ম মডেলটি জিজ্ঞাসা করুন

আমার প্রশ্ন:

কোন পদ্ধতিটি সর্বোত্তম পারফরম্যান্স সরবরাহ করবে এবং এমন কোনও বিকল্প আছে যা আরও ভাল পারফরম্যান্স সরবরাহ করবে?


এছাড়াও আপনি একটি করতে পারেন অনেক অনেক ব্যবহারকারী ফর্ম অ্যাক্সেস করতে পারে কি লিঙ্কটি পদ্ধতির
কোড অর্থের জন্য

বিশেষত ব্যবহারকারীর ফর্ম অনুমতি জিজ্ঞাসা করার জন্য একটি সারণী তৈরি সম্পর্কে কী? user_form_permissionশুধু ধারণকারী টেবিল user_idএবং form_id। এটি পড়ার অনুমতিগুলিকে একটি হাওয়া বানাবে, তবে অনুমতিগুলি আপডেট করা আরও শক্ত হবে।
পিটিটিটন

ব্যবহারকারীর_পরিষ্কার_সারণের টেবিলের সমস্যাটি হ'ল আমরা অন্যান্য সত্তাগুলির কাছে অনুমতিগুলি প্রসারিত করতে চাই যার জন্য প্রতিটি সত্তার জন্য পৃথক সারণির প্রয়োজন হবে।
টিম

1
@ টিম তবে এটি এখনও 5 টি ক্যোয়ারী। এটি যদি কোনও সুরক্ষিত সদস্যের অঞ্চলে থাকে তবে এটি কোনও সমস্যা নাও হতে পারে। তবে এটি যদি সর্বজনীন মুখোমুখি ইউআরএলটিতে থাকে যা প্রতি সেকেন্ডে প্রচুর অনুরোধ পেতে পারে তবে আমি আপনাকে এটিকে কিছুটা অনুকূল করতে চাই। পারফরম্যান্সের কারণে, আমি প্রতিবার কোনও ফর্ম বা দলের সদস্যকে মডেল পর্যবেক্ষকের মাধ্যমে যুক্ত করা বা অপসারণের সময় পৃথক টেবিলটি বজায় রাখতে পারি (যা আমি ক্যাশে করতে পারি)। তারপরে, প্রতিটি অনুরোধে, আমি তা ক্যাশে থেকে পেয়ে যাব। আমি এই প্রশ্ন এবং সমস্যাটি খুব আকর্ষণীয় মনে করি এবং অন্যরা কী ভাববে তা জানতে আগ্রহী। এই প্রশ্নটি আরও ভোট এবং জবাব প্রাপ্য, একটি অনুগ্রহ শুরু করেছেন :)
রাউল ২

1
আপনি একটি নির্ধারিত কাজ হিসাবে রিফ্রেশ করতে পারেন যা একটি বস্তুগত দৃষ্টিভঙ্গি বিবেচনা করতে পারেন। এইভাবে আপনি সবসময় তুলনামূলকভাবে আপ টু ডেট ফলাফলগুলি দ্রুত পেতে পারেন।
apokryfos

উত্তর:


2

আমি একটি এসকিউএল ক্যোয়ারী করব যা পিএইচপি করার চেয়ে আরও ভাল পারফর্ম করতে চলেছে

এটার মতো কিছু:

User::where('id', $request->user()->id)
    ->join('group_users', 'user.id', 'group_users.user_id')
    ->join('team_users', 'user.id', 'team_users.user_id',)
    ->join('form_owners as user_form_owners', function ($join) {
        $join->on('users.id', 'form_owners.owner_id')
            ->where('form_owners.owner_type', User::class);
    })
    ->join('form_owners as group_form_owners', function ($join) {
        $join->on('group_users.group_id', 'form_owners.owner_id')
            ->where('form_owners.owner_type', Group::class);
    })
    ->join('form_owners as team_form_owners', function ($join) {
        $join->on('team_users.team_id', 'form_owners.owner_id')
           ->where('form_owners.owner_type', Team::class);
    })
    ->join('forms', function($join) {
        $join->on('forms.id', 'user_form_owners.form_id')
            ->orOn('forms.id', 'group_form_owners.form_id')
            ->orOn('forms.id', 'team_form_owners.form_id');
    })
    ->selectRaw('forms.*')
    ->get();

আমার মাথার শীর্ষ থেকে এবং অনির্ধারিতভাবে এটি আপনার ব্যবহারকারীর, তার গোষ্ঠী এবং এই টিমের মালিকানাধীন সমস্ত ফর্মগুলি পাওয়া উচিত।

তবে এটি গ্রুপ এবং দলগুলিতে ব্যবহারকারীর দেখার ফর্মগুলির অনুমতিগুলি দেখে না।

আমি নিশ্চিত নই যে আপনি কীভাবে আপনার লেখককে এটির জন্য সেট আপ করেছেন এবং সুতরাং আপনার এটির জন্য আপনার ডিবি কাঠামোর কোনও পার্থক্য এবং কোনও পার্থক্য পরিবর্তন করতে হবে।


উত্তরের জন্য ধন্যবাদ. তবে কীভাবে ডাটাবেস থেকে ডেটা পাবেন তা নিয়ে সমস্যাটি ছিল না। সমস্যাটি হ'ল, প্রতিটি অনুরোধে কীভাবে এটি প্রতিবার দক্ষতার সাথে পাওয়া যায়, যখন অ্যাপটিতে কয়েক হাজার ফর্ম এবং প্রচুর দল এবং সদস্য রয়েছে। আপনার যোগদানের ORক্লজ রয়েছে, যা আমি সন্দেহ করি যে সেখানে ধীরগতি হবে। সুতরাং প্রতিটি অনুরোধে এটি আঘাত করা উন্মাদ হবে আমি বিশ্বাস করি।
রাউল

আপনি কাঁচা মাইএসকিউএল কোয়েরি বা দৃষ্টিভঙ্গি বা পদ্ধতিগুলির মতো কোনও জিনিস ব্যবহার করে আরও ভাল গতি পেতে সক্ষম হতে পারেন তবে প্রতিবার যখন আপনি ডেটা চান তখন আপনাকে এই জাতীয় কল করতে হবে। ফলাফলের ক্যাচিং এখানে সহায়তা করতে পারে।
জোশ

আমি যখন এই পারফর্ম্যান্টটি তৈরি করার একমাত্র উপায়টি ভাবছি তখন ক্যাশে হচ্ছে, এটি প্রতিবার পরিবর্তন হওয়ার সাথে সাথে এই মানচিত্রটি বজায় রাখতে সর্বদা ব্যয় হয়। কল্পনা করুন যে আমি একটি নতুন ফর্ম তৈরি করেছি, যা, যদি আমার অ্যাকাউন্টে কোনও দল নির্ধারিত হয় তবে হাজার হাজার ব্যবহারকারী এতে অ্যাক্সেস পেতে পারে। এরপর কি? কয়েক হাজার সদস্যের নীতিমালা পুনরায় ক্যাশে?
রাউল

আজীবন সঙ্গে ক্যাশের সমাধান রয়েছে (যেমন ল্যারাভেলের ক্যাশে বিমূর্তি) এবং আপনি কোনও পরিবর্তন করার পরে ঠিক প্রভাবিত ক্যাশে সূচকগুলিও সরিয়ে ফেলতে পারেন। আপনি যদি এটি সঠিকভাবে ব্যবহার করেন তবে ক্যাশেটি আসল গেম-চেঞ্জার। কীভাবে কীভাবে কনফিগার করবেন তা ডেটা পড়ার এবং আপডেটের উপর নির্ভর করে।
গনজালো

2

সংক্ষিপ্ত উত্তর

তৃতীয় বিকল্প: Query all identifiers for all permissions (5), then query the Form model using the identifiers in an IN() statement

$teamMorphType  = Relation::getMorphedModel('team');
$groupMorphType = Relation::getMorphedModel('group');
$formMorphType  = Relation::getMorphedModel('form');

$permissible = [
    $teamMorphType  => [$user->team_id],
    $groupMorphType => [],
    $formMorphType  => [],
];

foreach ($user->permissible as $permissible) {
    switch ($permissible->permissible_type) {
        case $teamMorphType:
        case $groupMorphType:
        case $formMorphType:
            $permissible[$permissible->permissible_type][] = $permissible->permissible_id;
            break;
    }
}

$forms = Form::query()
             ->where('user_id', '=', $user->id)
             ->orWhereIn('id', $permissible[$fromMorphType])
             ->orWhereIn('team_id', $permissible[$teamMorphType])
             ->orWhereIn('group_id', $permissible[$groupMorphType])
             ->get();

দীর্ঘ উত্তর

একদিকে, (কোড) আপনি কোডগুলিতে যা করতে পারেন তার সবকিছুই ক্যোয়ারিতে না করাই ভাল পারফরম্যান্স-ভিত্তিক।

অন্যদিকে, প্রয়োজনের তুলনায় ডাটাবেস থেকে আরও বেশি ডেটা প্রাপ্ত করা ইতিমধ্যে অনেক বেশি ডেটা (র‍্যামের ব্যবহার এবং এই জাতীয়)।

আমার দৃষ্টিকোণ থেকে, আপনার মধ্যে কিছু দরকার এবং কেবলমাত্র আপনি জানবেন যে সংখ্যাটির উপর নির্ভর করে ভারসাম্যটি কোথায় থাকবে।

আমি বেশ কয়েকটি ক্যোয়ারী চালানোর পরামর্শ দেব, আপনি প্রস্তাবিত শেষ বিকল্প ( Query all identifiers for all permissions (5), then query the Form model using the identifiers in an IN() statement):

  1. সমস্ত অনুমতিগুলির জন্য সমস্ত সনাক্তকারীকে জিজ্ঞাসা করুন (5 টি কোয়েরি)
  2. সমস্ত ফর্মের ফলাফলগুলিকে স্মৃতিতে মার্জ করুন এবং অনন্য মান পাবেন array_unique($ids)
  3. আইএন () বিবৃতিতে শনাক্তকারীদের ব্যবহার করে ফর্ম মডেলটি অনুসন্ধান করুন।

আপনি প্রস্তাবিত তিনটি বিকল্প চেষ্টা করতে পারেন এবং একাধিকবার ক্যোরি চালানোর জন্য কোনও সরঞ্জাম ব্যবহার করে পারফরম্যান্স পর্যবেক্ষণ করতে পারেন তবে আমি 99% নিশ্চিত যে শেষটি আপনাকে সেরা পারফরম্যান্স দেবে।

আপনি কোন ডাটাবেসটি ব্যবহার করছেন তার উপর নির্ভর করে এটিও অনেক পরিবর্তন করতে পারে তবে উদাহরণস্বরূপ যদি আমরা মাইএসকিউএল সম্পর্কে কথা বলি; খুব বড় ক্যোয়ারিতে আরও বেশি ডাটাবেস সংস্থান ব্যবহার করা হবে, যা কেবলমাত্র সহজ অনুসন্ধানগুলির চেয়ে বেশি সময় ব্যয় করবে না, তবে লেখাগুলি থেকে টেবিলটি লক করে দেবে এবং এটি ডেডলক ত্রুটি তৈরি করতে পারে (যদি আপনি কোন গোলাম সার্ভার ব্যবহার না করেন)।

অন্যদিকে, ফর্ম আইডির সংখ্যা যদি খুব বড় হয় তবে আপনার অনেকগুলি স্থানধারীর জন্য ত্রুটি থাকতে পারে, সুতরাং আপনি 500 টি আইডির গ্রুপগুলিতে প্রশ্নগুলি কাটাতে চাইতে পারেন, এটি সীমা হিসাবে অনেকটা নির্ভর করে আকারে, বাইন্ডিংয়ের সংখ্যায় নয়), এবং ফলাফলগুলিকে মেমরিতে মিশ্রিত করে। এমনকি যদি আপনি একটি ডাটাবেস ত্রুটি না পান তবে আপনি পারফরম্যান্সেও একটি বড় পার্থক্য দেখতে পাবেন (আমি এখনও মাইএসকিউএল সম্পর্কে কথা বলছি)।


বাস্তবায়ন

আমি ধরে নেব যে এটি ডাটাবেস স্কিম:

users
  - id
  - team_id

forms
  - id
  - user_id
  - team_id
  - group_id

permissible
  - user_id
  - permissible_id
  - permissible_type

সুতরাং জায়েজযোগ্য এটি ইতিমধ্যে একটি কনফিগার করা পলিমারফিক সম্পর্ক

সুতরাং, সম্পর্কগুলি হবে:

  • নিজস্ব ফর্ম: users.id <-> form.user_id
  • দলটির ফর্মের মালিকানা: users.team_id <-> form.team_id
  • একটি ফর্মের মালিক এমন একটি গোষ্ঠীর অনুমতি রয়েছে: permissible.user_id <-> users.id && permissible.permissible_type = 'App\Team'
  • একটি ফর্মের মালিকানাধীন একটি দলে অনুমতি রয়েছে: permissible.user_id <-> users.id && permissible.permissible_type = 'App\Group'
  • একটি ফর্ম অনুমোদিত: permissible.user_id <-> users.id && permissible.permissible_type = 'App\From'

সরলকরণ সংস্করণ:

$teamMorphType  = Relation::getMorphedModel('team');
$groupMorphType = Relation::getMorphedModel('group');
$formMorphType  = Relation::getMorphedModel('form');

$permissible = [
    $teamMorphType  => [$user->team_id],
    $groupMorphType => [],
    $formMorphType  => [],
];

foreach ($user->permissible as $permissible) {
    switch ($permissible->permissible_type) {
        case $teamMorphType:
        case $groupMorphType:
        case $formMorphType:
            $permissible[$permissible->permissible_type][] = $permissible->permissible_id;
            break;
    }
}

$forms = Form::query()
             ->where('user_id', '=', $user->id)
             ->orWhereIn('id', $permissible[$fromMorphType])
             ->orWhereIn('team_id', $permissible[$teamMorphType])
             ->orWhereIn('group_id', $permissible[$groupMorphType])
             ->get();

বিস্তারিত সংস্করণ:

// Owns Form
// users.id <-> forms.user_id
$userId = $user->id;

// Team owns Form
// users.team_id <-> forms.team_id
// Initialise the array with a first value.
// The permissions polymorphic relationship will have other teams ids to look at
$teamIds = [$user->team_id];

// Groups owns Form was not mention, so I assume there is not such a relation in user.
// Just initialise the array without a first value.
$groupIds = [];

// Also initialise forms for permissions:
$formIds = [];

// Has permissions to a group that owns a Form
// permissible.user_id <-> users.id && permissible.permissible_type = 'App\Team'
$teamMorphType = Relation::getMorphedModel('team');
// Has permissions to a team that owns a Form
// permissible.user_id <-> users.id && permissible.permissible_type = 'App\Group'
$groupMorphType = Relation::getMorphedModel('group');
// Has permission to a Form
// permissible.user_id <-> users.id && permissible.permissible_type = 'App\Form'
$formMorphType = Relation::getMorphedModel('form');

// Get permissions
$permissibles = $user->permissible()->whereIn(
    'permissible_type',
    [$teamMorphType, $groupMorphType, $formMorphType]
)->get();

// If you don't have more permissible types other than those, then you can just:
// $permissibles = $user->permissible;

// Group the ids per type
foreach ($permissibles as $permissible) {
    switch ($permissible->permissible_type) {
        case $teamMorphType:
            $teamIds[] = $permissible->permissible_id;
            break;
        case $groupMorphType:
            $groupIds[] = $permissible->permissible_id;
            break;
        case $formMorphType:
            $formIds[] = $permissible->permissible_id;
            break;
    }
}

// In case the user and the team ids are repeated:
$teamIds = array_values(array_unique($teamIds));
// We assume that the rest of the values will not be repeated.

$forms = Form::query()
             ->where('user_id', '=', $userId)
             ->orWhereIn('id', $formIds)
             ->orWhereIn('team_id', $teamIds)
             ->orWhereIn('group_id', $groupIds)
             ->get();

সংস্থানসমূহ ব্যবহৃত:

ডাটাবেস কর্মক্ষমতা:

  • ডাটাবেসের প্রশ্ন (ব্যবহারকারী বাদে): 2 ; একটি অনুমোদিত হতে এবং অন্য একটি ফর্ম পেতে।
  • যোগ দেয় না !!
  • সর্বনিম্ন ওআরএস সম্ভব () user_id = ? OR id IN (?..) OR team_id IN (?...) OR group_id IN (?...)

পিএইচপি, স্মৃতিতে, কর্মক্ষমতা:

  • foreach ভিতরে একটি স্যুইচ সঙ্গে জায়েজ লুপিং ।
  • array_values(array_unique()) আইডি পুনরাবৃত্তি এড়ানোর জন্য।
  • মেমরি, আইডি 3 অ্যারে ( $teamIds, $groupIds, $formIds)
  • স্মৃতিতে, প্রাসঙ্গিক অনুমতিগুলি সুস্পষ্ট সংগ্রহ (এটি যদি প্রয়োজন হয় তবে অনুকূলিত করা যেতে পারে)।

সুবিধা - অসুবিধা

পেশাদাররা:

  • সময় : একক ক্যোয়ারির বারের যোগফল এবং ওআর-এর সাথে একটি বড় ক্যোয়ারির সময়ের চেয়ে কম হয়।
  • ডিবি রিসোর্সস: মাইএসকিউএল রিসোর্সগুলি যোগ বা বিবৃতি সহ একটি কোয়েরি দ্বারা ব্যবহৃত হয়, এটির পৃথক ক্যোয়ারীর যোগফলের চেয়ে বড়।
  • টাকা : পিএইচপি সংস্থানগুলির চেয়ে বেশি ব্যয়বহুল, খুব কম ডাটাবেস সংস্থান (প্রসেসর, র‌্যাম, ডিস্ক রিড ইত্যাদি)।
  • লক্স : আপনি যদি কেবল পঠনযোগ্য স্লেভ সার্ভারকে জিজ্ঞাসা করছেন না, আপনার প্রশ্নগুলি কম সারিগুলি পড়ার লকগুলিকে তৈরি করবে (পঠিত লকটি মাইএসকিউএলে ভাগ করা আছে, সুতরাং এটি অন্য পড়াটি লক করবে না, তবে এটি কোনও লিখনকে ব্লক করবে)।
  • স্কেলেবল : এই পদ্ধতির সাহায্যে ক্যোয়ারিকে খণ্ডিত করার মতো আরও পারফরম্যান্স অনুকূলকরণ করতে পারবেন ations

কনস:

  • কোড সংস্থানসমূহ : ডাটাবেসের পরিবর্তে কোডে গণনা করা কোডের উদাহরণে স্পষ্টতই বেশি সংস্থান গ্রহণ করবে তবে বিশেষত র‌্যামের মধ্যে মাঝারি তথ্য সংরক্ষণ করবে। আমাদের ক্ষেত্রে এটি কেবল আইডির একটি অ্যারে হবে, যা সত্যিই কোনও সমস্যা হওয়া উচিত নয়।
  • রক্ষণাবেক্ষণ : আপনি যদি লারাভেলের সম্পত্তি এবং পদ্ধতিগুলি ব্যবহার করেন এবং আপনি ডাটাবেসে কোনও পরিবর্তন করেন তবে আপনি আরও স্পষ্ট প্রশ্ন এবং প্রক্রিয়াজাতকরণের চেয়ে কোডে আপডেট করা সহজ হবে।
  • Overkilling? : কিছু ক্ষেত্রে, যদি ডেটাটি এত বড় না হয় তবে পারফরম্যান্সের অনুকূলকরণের জন্য অতিরিক্ত খরচ করা যেতে পারে।

কর্মক্ষমতা পরিমাপ কিভাবে

পারফরম্যান্সটি কীভাবে পরিমাপ করবেন সে সম্পর্কে কিছু সূত্র?

  1. স্লো ক্যোয়ারী লগগুলি
  2. বিশ্লেষণ সারণী
  3. টেবিল স্থিতির মতো দেখান
  4. ব্যাখ্যা ; এক্সটেন্ডেড এক্সপ্লেইন আউটপুট ফর্ম্যাট ; ব্যাখ্যার ব্যবহার ; আউটপুট ব্যাখ্যা
  5. সতর্কতাগুলি দেখান

কিছু আকর্ষণীয় প্রোফাইলিংয়ের সরঞ্জাম:


প্রথম লাইনটি কী? ক্যোয়ারি ব্যবহার করা প্রায় সর্বদা ভাল পারফরম্যান্স বুদ্ধিমান, কারণ পিএইচপি-তে বিভিন্ন লুপ বা অ্যারে ম্যানিপুলেশন চালানো ধীর হয়।
শিখার

আপনার যদি একটি ছোট ডাটাবেস থাকে বা আপনার ডাটাবেস মেশিনটি আপনার কোড উদাহরণের চেয়ে অনেক বেশি শক্তিশালী বা ডেটাবেস ল্যাটেন্সি খুব খারাপ, তবে হ্যাঁ, মাইএসকিউএল দ্রুত হয়, তবে সাধারণত এটি হয় না।
গঞ্জালো

আপনি যখন একটি ডাটাবেস ক্যোয়ারী অনুকূলিত করেন, তখন আপনাকে কার্যকর করার সময়, সারিগুলির সংখ্যাটি এবং সর্বাধিক গুরুত্বপূর্ণভাবে পরীক্ষিত সারিগুলির সংখ্যা বিবেচনা করা উচিত। যদি টিম বলছেন যে অনুসন্ধানগুলি ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে বেড়েছে, তবে আমি ধরে নিই যে ডেটা বৃদ্ধি পাচ্ছে, এবং সেজন্য সারিগুলির সংখ্যা। তদ্ব্যতীত, প্রোগ্রামিং ভাষা হওয়ায় ডাটাবেস প্রক্রিয়াজাতকরণের জন্য অনুকূলিত হয় না।
গঞ্জালো

তবে আপনার আমার উপর বিশ্বাস করার দরকার নেই, আপনার সমাধানের জন্য আপনি এক্সপ্ল্লেইন চালাতে পারেন , তারপরে আপনি এটিকে আমার সহজ সমাধানগুলির সমাধানের জন্য চালাতে পারেন, এবং পার্থক্যটি দেখতে পারেন, এবং তারপরে ভাবেন যে কোনও সাধারণ array_merge()এবং array_unique()একগুচ্ছ এইডস, সত্যিই আপনার প্রক্রিয়া ধীর।
গনজালো

10 টির মধ্যে 9 ক্ষেত্রে মাইএসকিএল ডাটাবেস একই মেশিনে চালিত হয় যা কোড চালায়। ডেটা স্তরটি ডেটা পুনরুদ্ধারের জন্য ব্যবহার করা বোঝানো হয় এবং এটি বড় সেটগুলি থেকে ডেটার টুকরা নির্বাচন করার জন্য অনুকূলিত হয়। আমি এখনও এমন পরিস্থিতি দেখতে পাইনি যেখানে array_unique()একটি GROUP BY/ SELECT DISTINCTবিবৃতি চেয়ে দ্রুততর হয় ।
শিখা

0

আপনি খালি কেন আপনার প্রয়োজনীয় ফর্মগুলি জিজ্ঞাসা করতে পারবেন না তার পরিবর্তে Form::all()এবং এর পরে শৃঙ্খলাবদ্ধfilter() ফাংশন ?

তাই ভালো:

public function index() {
    $forms = $user->forms->merge($user->team->forms)->merge($user->permissible->groups->forms);
}

হ্যাঁ, এটি কয়েকটি প্রশ্ন করে:

  • জন্য একটি জিজ্ঞাসা $user
  • একের জন্য $user->team
  • একের জন্য $user->team->forms
  • একের জন্য $user->permissible
  • একের জন্য $user->permissible->groups
  • একের জন্য $user->permissible->groups->forms

তবে, পক্ষের দিকটি হ'ল আপনাকে আর নীতিটি ব্যবহার করার দরকার নেই , কারণ আপনি জানেন যে $formsপ্যারামিটারের সমস্ত ফর্ম ব্যবহারকারীর জন্য অনুমোদিত।

সুতরাং এই সমাধানটি ডাটাবেসে আপনার যত পরিমাণ ফর্ম রয়েছে তার জন্য কাজ করবে।

ব্যবহার সম্পর্কে একটি নোট merge()

merge()সংগ্রহগুলিকে মার্জ করে এবং ডুপ্লিকেট ফর্ম আইডিকে এটি ইতিমধ্যে খুঁজে পেয়েছে discard সুতরাং যদি কোনও কারণে teamসম্পর্ক থেকে কোনও ফর্মও সরাসরি সম্পর্কিত হয় তবে userএটি একবারে মার্জ করা সংকলনে একবার দেখাবে।

কারণ এটি প্রকৃতপক্ষে এমন একটি Illuminate\Database\Eloquent\Collectionনিজস্ব merge()ফাংশন রয়েছে যা স্পষ্টত মডেল আইডির জন্য পরীক্ষা করে। সুতরাং 2 টি বিভিন্ন সংগ্রহের সামগ্রী যেমন Postsএবং এর সাথে মার্জ করার সময় আপনি আসলে এই কৌশলটি ব্যবহার করতে পারবেন না Users, কারণ আইডি সহ কোনও ব্যবহারকারী এবং আইডির সাথে 3কোনও পোস্ট 3এই ক্ষেত্রে বিরোধ করবে এবং একীভূত সংগ্রহটিতে কেবল পরবর্তী (পোস্ট) খুঁজে পাওয়া যাবে।


আপনি যদি এটি আরও দ্রুততর হতে চান তবে আপনার ডিবি ফ্যাসাদ ব্যবহার করে একটি কাস্টম ক্যোয়ারী তৈরি করা উচিত, এর লাইনের সাথে কিছু:

// Select forms based on a subquery that returns a list of id's.
$forms = Form::whereIn(
    'id',
    DB::select('id')->from('users')->where('users.id', $user->id)
        ->join('teams', 'users.id', '=', 'teams.user_id')
        ...
)->get();

আপনার প্রকৃত ক্যোয়ারী অনেক বড় কারণ আপনার অনেক সম্পর্ক রয়েছে।

এখানে মূল পারফরম্যান্সের উন্নতিটি আসল সত্য থেকে আসে যে ভারী কাজ (উপশহর) সম্পূর্ণরূপে বর্ণনামূলক মডেলের যুক্তিকে বাইপাস করে। তারপরে যা করা বাকি রয়েছে তা হ'ল আইডির তালিকাটি ফাংশনটিতে whereInআপনার Formঅবজেক্টগুলির তালিকা পুনরুদ্ধার করতে ।


0

আমি বিশ্বাস করি যে আপনি এটির জন্য অলস সংগ্রহগুলি ব্যবহার করতে পারেন (লারাভেল x.x) এবং সেগুলিতে প্রবেশের আগে আগ্রহী লোডগুলি।

public function index(Request $request)
{
   // Eager Load relationships
   $request->user()->load(['forms', 'team.forms', 'permissible.group']);
   // Use cursor instead of all to return a LazyCollection instance
   $forms = Form::cursor()->filter(function($form) use ($request) {
         return $request->user()->can('view', $form);
   });
}
public function view(User $user, Form $form)
{
   return $user->forms->contains($form) ||
      $user->team->forms->contains($form) ||
      // $user->permissible->groups->forms($contains); // Assuming this line is a typo
      $user->permissible->groups->contains($form);
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.