C#.NET တွင် LINQ မေးခွန်းများကို အကောင်းဆုံးဖြစ်အောင် ပြုလုပ်ရန် နည်းလမ်းများ

နိဒါန်း

В ဤဆောင်းပါးတွင် အချို့သော optimization နည်းလမ်းများကို ထည့်သွင်းစဉ်းစားခဲ့သည်။ LINQ မေးခွန်းများ.
ဤနေရာတွင် ကျွန်ုပ်တို့သည် ဆက်စပ်သောကုဒ်ကို ပိုမိုကောင်းမွန်အောင်ပြုလုပ်ရန် နောက်ထပ်နည်းလမ်းအချို့ကို တင်ပြထားပါသည်။ LINQ မေးခွန်းများ.

အဲဒါကိုလူသိများတယ် လင့်ခ်(Language-Integrated Query) သည် ဒေတာရင်းမြစ်ကို မေးမြန်းရန်အတွက် ရိုးရှင်းပြီး အဆင်ပြေသော ဘာသာစကားတစ်ခုဖြစ်သည်။

А SQL သို့ LINQ DBMS တွင် ဒေတာဝင်ရောက်ခြင်းအတွက် နည်းပညာတစ်ခုဖြစ်သည်။ ဤအရာသည် ဒေတာနှင့်အလုပ်လုပ်ရန် အစွမ်းထက်သောကိရိယာဖြစ်ပြီး၊ မေးမြန်းချက်များကို ကြေငြာဘာသာစကားဖြင့်တည်ဆောက်ကာ၊ ထို့နောက်သို့ပြောင်းလဲမည့် SQL မေးခွန်းများ platform နှင့် execution အတွက် database server သို့ ပေးပို့သည်။ ကျွန်ုပ်တို့၏ကိစ္စတွင်၊ DBMS အားဖြင့်ကျွန်ုပ်တို့ဆိုလိုသည်။ MS SQL Server ဖြစ်သည်.

သို့သျောလညျး LINQ မေးခွန်းများ အကောင်းမွန်ဆုံး ရေးသားထားသော စာများအဖြစ်သို့ မပြောင်းလဲပါ။ SQL မေးခွန်းများအတွေ့အကြုံရှိ DBA သည် ပိုမိုကောင်းမွန်အောင်ပြုလုပ်ခြင်း၏ ကွဲပြားချက်များအားလုံးကို ရေးနိုင်သည်။ SQL မေးခွန်းများ:

  1. အကောင်းဆုံးချိတ်ဆက်မှုများ (JOIN) နှင့် ရလဒ်များကို စစ်ထုတ်ခြင်း (နေရာ)
  2. ချိတ်ဆက်မှုများနှင့် အုပ်စုအခြေအနေများကို အသုံးပြုရာတွင် ကွဲလွဲချက်များစွာရှိသည်။
  3. အခြေအနေများကို အစားထိုးရာတွင် ကွဲပြားမှုများစွာရှိသည်။ IN အပေါ် တည်ရှိи မဝင်ပါ။, <> on တည်ရှိ
  4. ယာယီဇယားများ၊ CTE၊ table variable များမှတစ်ဆင့် ရလဒ်များကို အလယ်အလတ် သိမ်းဆည်းခြင်း။
  5. ဝါကျအသုံးပြုမှု (options) လမ်းညွှန်ချက်များ နှင့် ဇယားလမ်းညွှန်ချက်များ နဲ့ ( ... )
  6. ရွေးချယ်မှုများအတွင်း မလိုအပ်သောဒေတာဖတ်ခြင်းကို ဖယ်ရှားရန် အညွှန်းကိန်းအမြင်များကို အသုံးပြုခြင်း။

အဓိက စွမ်းဆောင်မှု ပိတ်ဆို့မှုများ ထွက်ပေါ်လာခြင်း ဖြစ်သည်။ SQL မေးခွန်းများ compiling လုပ်တဲ့အခါ LINQ မေးခွန်းများ သူတို့ဟာနေသောခေါင်းစဉ်:

  1. တောင်းဆိုချက်တစ်ခုတည်းတွင် အချက်အလက်ရွေးချယ်ရေးယန္တရားတစ်ခုလုံးကို စုစည်းမှု
  2. အဆုံးတွင် မလိုအပ်သော အချက်အလက်များစွာကို ဖတ်ရှုနိုင်စေသည့် တူညီသော ကုဒ်တုံးများကို ပွားခြင်း။
  3. အစိတ်အပိုင်းပေါင်းစုံအခြေအနေအုပ်စုများ (ယုတ္တိဗေဒ “နှင့်” နှင့် “သို့မဟုတ်”) - ႏွင့္ и ORရှုပ်ထွေးသောအခြေအနေများတွင် ပေါင်းစပ်ခြင်းဖြင့်၊ optimizer သည် လိုအပ်သောကွက်လပ်များအတွက် သင့်လျော်သော အစုအဝေးမဟုတ်သော အညွှန်းများ ပါရှိခြင်းဟူသောအချက်ကို ဖြစ်ပေါ်စေသည်၊ နောက်ဆုံးတွင် အစုလိုက်အပြုံလိုက်အညွှန်းကို စကန်ဖတ်ရန် စတင်သည် (INDEX စကင်န်) အခြေအနေအုပ်စုအလိုက်
  4. subqueries ၏ နက်ရှိုင်းသော အသိုက်များကို ခွဲခြမ်းစိတ်ဖြာခြင်းသည် အလွန်ပြဿနာတက်စေသည်။ SQL ထုတ်ပြန်ချက် developer များဘက်မှ စုံစမ်းမေးမြန်းမှု အစီအစဉ်နှင့် ခွဲခြမ်းစိတ်ဖြာခြင်း။ DBA

ပိုကောင်းအောင်နည်းလမ်းများ

ယခု ပိုမိုကောင်းမွန်အောင်ပြုလုပ်ခြင်းနည်းလမ်းများသို့ တိုက်ရိုက်ရွှေ့ကြပါစို့။

1) ထပ်လောင်းအညွှန်းကိန်း

မေးခွန်းတစ်ခုလုံးကို ပင်မဇယားတစ်ခု သို့မဟုတ် နှစ်ခု (အပလီကေးရှင်းများ-လူ-လည်ပတ်မှုများ) နှင့် စံသတ်မှတ်ချက်များ (ပိတ်လိုက်၊ ဖျက်လိုက်၊ ဖွင့်ထား၊ အခြေအနေ) ဖြင့် ပင်မရွေးချယ်ရေးဇယားများတွင် စစ်ထုတ်မှုများကို ထည့်သွင်းစဉ်းစားရန် အကောင်းဆုံးဖြစ်သည်။ ဖော်ထုတ်ထားသော နမူနာများအတွက် သင့်လျော်သော အညွှန်းကိန်းများ ဖန်တီးရန် အရေးကြီးပါသည်။

ဤအကွက်များကို ရွေးချယ်သည့်အခါ ဤဖြေရှင်းချက်သည် query သို့ ပြန်သွားသော သတ်မှတ်ချက်များကို သိသိသာသာ ကန့်သတ်ထားသည်။

ဥပမာအားဖြင့်၊ ကျွန်ုပ်တို့တွင် လျှောက်လွှာပေါင်း 500000 ရှိသည်။ သို့သော်၊ အသက်ဝင်သော application ပေါင်း 2000 သာရှိသည်။ ထို့နောက် မှန်ကန်စွာရွေးချယ်ထားသော အညွှန်းသည် ကျွန်ုပ်တို့အား ကယ်တင်မည်ဖြစ်သည်။ INDEX စကင်န် ကြီးမားသောဇယားတစ်ခုပေါ်တွင် အစုလိုက်အပြုံလိုက်မဟုတ်သော အညွှန်းတစ်ခုမှတစ်ဆင့် ဒေတာကို လျင်မြန်စွာရွေးချယ်နိုင်စေမည်ဖြစ်သည်။

ထို့အပြင်၊ အညွှန်းကိန်းများမရှိခြင်းကိုလည်း ဆန်းစစ်မေးမြန်းမှုအစီအစဉ်များကို ခွဲခြမ်းစိတ်ဖြာရန် သို့မဟုတ် စနစ်ကြည့်ရှုမှုစာရင်းဇယားများ စုဆောင်းခြင်းအတွက် အချက်ပြမှုများမှတစ်ဆင့် ဖော်ထုတ်နိုင်သည် MS SQL Server ဖြစ်သည်:

  1. sys.dm_db_missing_index_groups
  2. sys.dm_db_missing_index_group_stats
  3. sys.dm_db_missing_index_details

ကြည့်ရှုမှုဒေတာအားလုံးတွင် spatial indexes များမှလွဲ၍ ပျောက်ဆုံးနေသောအညွှန်းများအကြောင်း အချက်အလက်များပါရှိသည်။

သို့ရာတွင်၊ အညွှန်းများနှင့် သိမ်းဆည်းခြင်းများသည် ညံ့ဖျင်းစွာရေးသားခြင်း၏ အကျိုးဆက်များကို တိုက်ဖျက်သည့် နည်းလမ်းများဖြစ်သည်။ LINQ မေးခွန်းများ и SQL မေးခွန်းများ.

ဘဝ၏ကြမ်းတမ်းသောအလေ့အကျင့်ကိုပြသထားသည့်အတိုင်း၊ အချို့သောသတ်မှတ်ရက်များတွင် လုပ်ငန်းအင်္ဂါရပ်များကိုအကောင်အထည်ဖော်ရန် စီးပွားရေးလုပ်ငန်းတစ်ခုအတွက် မကြာခဏအရေးကြီးပါသည်။ ထို့ကြောင့်၊ လေးလံသောတောင်းဆိုမှုများကို caching ဖြင့်နောက်ခံသို့လွှဲပြောင်းပေးလေ့ရှိသည်။

အသုံးပြုသူသည် နောက်ဆုံးပေါ်ဒေတာကို အမြဲမလိုအပ်ဘဲ အသုံးပြုသူမျက်နှာပြင်၏ လက်ခံနိုင်လောက်သော တုံ့ပြန်မှုအဆင့်ရှိသောကြောင့် ၎င်းသည် တစ်စိတ်တစ်ပိုင်းမျှတပါသည်။

ဤချဉ်းကပ်မှုသည် လုပ်ငန်းလိုအပ်ချက်များကို ဖြေရှင်းနိုင်စေသော်လည်း နောက်ဆုံးတွင် ပြဿနာများကို ဖြေရှင်းချက်များကို နှောင့်နှေးရုံမျှဖြင့် သတင်းအချက်အလက်စနစ်၏ စွမ်းဆောင်ရည်ကို လျော့နည်းစေသည်။

ထပ်ထည့်ရန် လိုအပ်သော အညွှန်းများကို ရှာဖွေသည့် လုပ်ငန်းစဉ်တွင် အကြံပြုချက်များကိုလည်း မှတ်သားထိုက်ပါသည်။ MS SQL အောက်ပါအခြေအနေများအောက်တွင် အပါအဝင် ပိုမိုကောင်းမွန်အောင်ပြုလုပ်ခြင်းသည် မှားယွင်းနေနိုင်သည်-

  1. အလားတူနယ်ပယ်အစုံပါသော အညွှန်းကိန်းများ ရှိနှင့်ပြီးဖြစ်ပါက
  2. အညွှန်းကိန်းကန့်သတ်ချက်များကြောင့် ဇယားရှိကွက်လပ်များကို အညွှန်းမရေးနိုင်ပါက (အသေးစိတ်ဖော်ပြထားသည် ဒီမှာ).

2) attribute များကို attribute အသစ်တစ်ခုသို့ ပေါင်းစပ်ခြင်း။

တခါတရံ အခြေအနေများအုပ်စုအတွက် အခြေခံအဖြစ် ဆောင်ရွက်သော ဇယားတစ်ခုမှ အချို့သော အကွက်များကို အကွက်အသစ်တစ်ခုကို မိတ်ဆက်ခြင်းဖြင့် အစားထိုးနိုင်သည်။

၎င်းသည် အများအားဖြင့် အမျိုးအစားတွင် bit သို့မဟုတ် ကိန်းပြည့်ဖြစ်သည့် အခြေအနေအကွက်များအတွက် အထူးသင့်လျော်သည်။

ဥပမာ:

IsClosed = 0 AND Canceled = 0 AND Enabled = 0 ဖြင့်အစားထိုးထားသည် အဆင့်အတန်း = ၂.

ဤအခြေအနေများကို ဇယားတွင် ပြည့်ပြည့်စုံစုံထည့်သွင်းထားကြောင်း သေချာစေရန်အတွက် ကိန်းပြည့်အခြေအနေ ရည်ညွှန်းချက်အား မိတ်ဆက်ပေးပါသည်။ ထို့နောက်၊ ဤ attribute အသစ်ကို အညွှန်းပြုထားသည်။

ကျွန်ုပ်တို့သည် မလိုအပ်သော တွက်ချက်မှုများမပါဘဲ ဒေတာကို ရယူအသုံးပြုသောကြောင့် စွမ်းဆောင်ရည်ပြဿနာအတွက် အခြေခံအဖြေတစ်ခုဖြစ်သည်။

၃) အမြင်ကို ရုပ်လုံးပေါ်စေခြင်း။

ကံမကောင်းစွာပဲ၊ LINQ မေးခွန်းများ ယာယီဇယားများ၊ CTEs နှင့် table variable များကို တိုက်ရိုက်အသုံးမပြုနိုင်ပါ။

သို့သော်၊ ဤကိစ္စအတွက် အကောင်းဆုံးဖြစ်အောင်လုပ်ရန် အခြားနည်းလမ်းတစ်ခုရှိသည် - အညွှန်းပြုထားသောအမြင်များ။

အခြေအနေအုပ်စု (အထက်ဥပမာမှ) IsClosed = 0 AND Canceled = 0 AND Enabled = 0 (သို့မဟုတ် အခြားသော အလားတူအခြေအနေများ) သည် ၎င်းတို့ကို အညွှန်းပြုထားသော မြင်ကွင်းတစ်ခုတွင် အသုံးပြုရန် ရွေးချယ်စရာတစ်ခုဖြစ်လာပြီး ကြီးမားသောအစုတစ်ခုမှ သေးငယ်သောဒေတာများကို သိမ်းဆည်းထားသည်။

ဒါပေမယ့် အမြင်တစ်ခုကို အကောင်အထည်ပေါ်လာတဲ့အခါ ကန့်သတ်ချက်တွေ အများကြီးရှိပါတယ်။

  1. subqueries, clauses များကို အသုံးပြု တည်ရှိ အစားထိုးအသုံးပြုသင့်သည်။ JOIN
  2. စာကြောင်းတွေသုံးလို့မရဘူး ပြည်ထောင်စု, အားလုံးပြည်ထောင်စု, ခြွင်းချက်, လမ်းဆုံ
  3. ဇယားအကြံဉာဏ်များနှင့် အပိုဒ်များကို သင်သုံး၍မရပါ။ options
  4. သံသရာနှင့်အလုပ်လုပ်ရန်မဖြစ်နိုင်ပါ။
  5. မတူညီသော ဇယားများမှ ဒေတာများကို မြင်ကွင်းတစ်ခုတည်းတွင် ပြသရန် မဖြစ်နိုင်ပါ။

ကိန်းညွှန်းထားသောအမြင်ကိုအသုံးပြုခြင်း၏ အမှန်တကယ်အကျိုးကို အမှန်တကယ် ညွှန်းကိန်းပြုလုပ်ခြင်းဖြင့်သာ ရရှိနိုင်ကြောင်း မှတ်သားထားရန် အရေးကြီးပါသည်။

သို့သော် မြင်ကွင်းတစ်ခုကို ခေါ်ဆိုသည့်အခါ၊ ဤအညွှန်းများကို အသုံးမပြုနိုင်ဘဲ ၎င်းတို့ကို ပြတ်သားစွာ အသုံးပြုရန် သင်သတ်မှတ်ရမည်၊ နှင့်အတူ (NOEXPAND).

၌ကတည်းက LINQ မေးခွန်းများ ဇယားအရိပ်အမြွက်များကို သတ်မှတ်ရန် မဖြစ်နိုင်သောကြောင့် သင်သည် အောက်ပါပုံစံ၏ "ထုပ်ပိုးခြင်း" အခြားကိုယ်စားပြုမှုကို ဖန်တီးရပါမည်-

CREATE VIEW ИМЯ_представления AS SELECT * FROM MAT_VIEW WITH (NOEXPAND);

4) ဇယားလုပ်ဆောင်ချက်များကိုအသုံးပြုခြင်း။

ဝင်တတ်တယ်။ LINQ မေးခွန်းများ ရှုပ်ထွေးသောဖွဲ့စည်းပုံဖြင့်ကြည့်ရှုမှုများအသုံးပြုသည့် ကြီးမားသောအတုံးများ သို့မဟုတ် လုပ်ကွက်များသည် အလွန်ရှုပ်ထွေးပြီး အကောင်းဆုံးလုပ်ဆောင်မှုပုံစံဖြင့် နောက်ဆုံးမေးမြန်းချက်တစ်ခုဖြစ်သည်။

Table Functions ကိုအသုံးပြုခြင်းအတွက် အဓိကအကျိုးကျေးဇူးများ LINQ မေးခွန်းများ:

  1. မြင်ကွင်းများကဲ့သို့ပင်၊ အရာဝတ္ထုတစ်ခုအဖြစ် သတ်မှတ်အသုံးပြုနိုင်သော်လည်း ထည့်သွင်းမှုဘောင်များကို သင်ဖြတ်သန်းနိုင်သည်-
    FUNCTION မှ (@param1၊ @param2 ...)
    ရလဒ်အနေဖြင့်၊ လိုက်လျောညီထွေရှိသော အချက်အလက်နမူနာကို ရရှိနိုင်ပါသည်။
  2. ဇယားလုပ်ဆောင်ချက်ကို အသုံးပြုခြင်းတွင်၊ အထက်တွင်ဖော်ပြထားသော အညွှန်းပြုအမြင်များကဲ့သို့ ပြင်းထန်သောကန့်သတ်ချက်များ မရှိပါ။
    1. ဇယားအကြံပြုချက်များ-
      ဖြတ်. လင့်ခ် သင်သည် မည်သည့်အညွှန်းများကို အသုံးပြုသင့်သည်ကို သတ်မှတ်၍ စုံစမ်းမေးမြန်းသည့်အခါ ဒေတာ သီးခြားခွဲထုတ်ခြင်းအဆင့်ကို ဆုံးဖြတ်၍မရပါ။
      ဒါပေမယ့် Function မှာ ဒီစွမ်းရည်တွေရှိပါတယ်။
      လုပ်ဆောင်ချက်ဖြင့်၊ သင်သည် အညွှန်းကိန်းများနှင့် ဒေတာ သီးခြားခွဲထုတ်ခြင်း အဆင့်များကို သတ်မှတ်ပေးသည့် မျှတသော စဉ်ဆက်မပြတ် လုပ်ဆောင်မှု စုံစမ်းမေးမြန်းမှု အစီအစဉ်ကို သင်ရရှိနိုင်ပါသည်။
    2. လုပ်ဆောင်ချက်ကို အသုံးပြုခြင်းဖြင့် အညွှန်းပြုထားသော အမြင်များနှင့် နှိုင်းယှဉ်ပါက ရရှိရန် ခွင့်ပြုသည်-
      • ရှုပ်ထွေးသောဒေတာနမူနာယူခြင်းဆိုင်ရာ ယုတ္တိဗေဒ ( loops များကိုအသုံးပြုသည့်တိုင်)
      • မတူညီသောဇယားများစွာမှဒေတာကိုရယူခြင်း။
      • ၏အသုံးပြုမှု ပြည်ထောင်စု и တည်ရှိ

  3. ပေးကမ်း options တူညီသောငွေကြေးထိန်းချုပ်မှုပေးရန် လိုအပ်သည့်အခါ အလွန်အသုံးဝင်သည်။ OPTION(MAXDOP N)query execution plan ၏ အမှာစာ၊ ဥပမာအားဖြင့်:
    • သင်မေးမြန်းမှုအစီအစဉ်ကို အတင်းအကြပ်ပြန်လည်ဖန်တီးမှုကို သတ်မှတ်နိုင်သည်။ ရွေးချယ်မှု (ပြန်လည်ပေါင်းစည်းရန်)
    • query တွင်သတ်မှတ်ထားသော join order ကိုအသုံးပြုရန် query plan အား အတင်းအကြပ်လုပ်ရန်ရှိမရှိ သင်သတ်မှတ်နိုင်ပါသည်။ ရွေးချယ်မှု (အတင်းအကြပ်အမိန့်)

    အကြောင်းအသေးစိတ် options ဖော်ပြခဲ့သည်။ ဒီမှာ.

  4. အကျဉ်းဆုံးနှင့် အလိုအပ်ဆုံး ဒေတာအပိုင်းကို အသုံးပြုခြင်း-
    ဒေတာအတွဲများကို ကန့်သတ်ချက်ဖြင့် စစ်ထုတ်ရန် လိုအပ်နေသေးသည့် (အညွှန်းပြုလုပ်ထားသော မြင်ကွင်းများကဲ့သို့) ကြီးမားသောဒေတာအစုံများကို ကက်ရှ်တွင် သိမ်းဆည်းရန် မလိုအပ်ပါ။
    ဥပမာအားဖြင့် Filter ဟူ၍ ဇယားတစ်ခုရှိသည်။ နေရာ နယ်ပယ်သုံးခုကို အသုံးပြုသည်။ (က၊ ခ၊ ဂ).

    သမရိုးကျအားဖြင့်၊ တောင်းဆိုမှုအားလုံးသည် စဉ်ဆက်မပြတ်အခြေအနေရှိသည်။ a = 0 နှင့် b = 0.

    သို့သော် လယ်ကွင်းများအတွက် တောင်းဆိုမှု c ပိုပြောင်းလဲနိုင်သည်။

    အခြေအနေရှိပါစေ။ a = 0 နှင့် b = 0 ၎င်းသည် ကျွန်ုပ်တို့အား လိုအပ်သော ရလဒ်များကို ထောင်ပေါင်းများစွာသော မှတ်တမ်းများတွင် ကန့်သတ်ရန် အမှန်တကယ် ကူညီပေးသော်လည်း အခြေအနေတွင် ရှိနေသည်။ с ရွေးချယ်မှုကို မှတ်တမ်းတစ်ရာအထိ ကျဉ်းမြောင်းစေသည်။

    ဤနေရာတွင် ဇယားလုပ်ဆောင်ချက်သည် ပိုမိုကောင်းမွန်သော ရွေးချယ်မှုတစ်ခု ဖြစ်နိုင်သည်။

    ထို့အပြင်၊ ဇယားလုပ်ဆောင်ချက်သည် လုပ်ဆောင်ချိန်၌ ပိုမိုခန့်မှန်းနိုင်ကာ တသမတ်တည်းဖြစ်သည်။

ဥပမာ

နမူနာအဖြစ် Questions database ကိုအသုံးပြု၍ နမူနာအကောင်အထည်ဖော်မှုကို ကြည့်ကြပါစို့။

တောင်းဆိုချက်တစ်ခုရှိတယ်။ SELECTဇယားများစွာကို ပေါင်းစပ်ပြီး တစ်ခုတည်းသော မြင်ကွင်း (OperativeQuestions) ကို အသုံးပြုကာ ဆက်နွယ်မှုကို အီးမေးလ်ဖြင့် စစ်ဆေးသည် (မှတဆင့်၊ တည်ရှိ) "လုပ်ငန်းဆောင်တာမေးခွန်းများ" သို့:

တောင်းဆိုချက် နံပါတ် ၁

(@p__linq__0 nvarchar(4000))SELECT
1 AS [C1],
[Extent1].[Id] AS [Id],
[Join2].[Object_Id] AS [Object_Id],
[Join2].[ObjectType_Id] AS [ObjectType_Id],
[Join2].[Name] AS [Name],
[Join2].[ExternalId] AS [ExternalId]
FROM [dbo].[Questions] AS [Extent1]
INNER JOIN (SELECT [Extent2].[Object_Id] AS [Object_Id],
[Extent2].[Question_Id] AS [Question_Id], [Extent3].[ExternalId] AS [ExternalId],
[Extent3].[ObjectType_Id] AS [ObjectType_Id], [Extent4].[Name] AS [Name]
FROM [dbo].[ObjectQuestions] AS [Extent2]
INNER JOIN [dbo].[Objects] AS [Extent3] ON [Extent2].[Object_Id] = [Extent3].[Id]
LEFT OUTER JOIN [dbo].[ObjectTypes] AS [Extent4] 
ON [Extent3].[ObjectType_Id] = [Extent4].[Id] ) AS [Join2] 
ON [Extent1].[Id] = [Join2].[Question_Id]
WHERE ([Extent1].[AnswerId] IS NULL) AND (0 = [Extent1].[Exp]) AND ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[OperativeQuestions] AS [Extent5]
WHERE (([Extent5].[Email] = @p__linq__0) OR (([Extent5].[Email] IS NULL) 
AND (@p__linq__0 IS NULL))) AND ([Extent5].[Id] = [Extent1].[Id])
));

မြင်ကွင်းသည် ရှုပ်ထွေးသောဖွဲ့စည်းပုံတစ်ခုပါရှိသည်- ၎င်းတွင် subquery ပါ၀င်ပြီး အမျိုးအစားခွဲခြင်းကို အသုံးပြုသည်။ ကွဲပြားယေဘူယျအားဖြင့် အရင်းအမြစ်-အလေးပေးလုပ်ဆောင်မှုတစ်ခုဖြစ်သည်။

OperativeQuestions မှနမူနာသည် မှတ်တမ်းပေါင်း တစ်သောင်းခန့်ဖြစ်သည်။

ဤမေးမြန်းချက်၏ အဓိကပြဿနာမှာ ပြင်ပမေးမြန်းမှုမှ မှတ်တမ်းများအတွက်၊ [OperativeQuestions] မြင်ကွင်းတွင် လုပ်ဆောင်ပြီးဖြစ်သည့် [Email] = @p__linq__0 အတွက် ကျွန်ုပ်တို့အား အထွက်ရွေးချယ်မှုအား ကန့်သတ်ခွင့်ပြုသည် (မှတဆင့် တည်ရှိ) ရာနှင့်ချီသောမှတ်တမ်းများ။

နောက်ဆက်တွဲအနေဖြင့် မှတ်တမ်းများကို [Email] = @p__linq__0 ဖြင့် တစ်ကြိမ် တွက်ချက်သင့်သည်၊ ထို့နောက် အဆိုပါ မှတ်တမ်းနှစ်ရာကို Id with Questions ဖြင့် ချိတ်ဆက်ထားသင့်ပြီး မေးမြန်းမှု မြန်ဆန်မည်ဖြစ်သည်။

အမှန်မှာ၊ ဇယားအားလုံး၏ ဆက်တိုက်ချိတ်ဆက်မှုတစ်ခု ရှိသည်- OperativeQuestions မှ Id ဖြင့် Id မေးခွန်းများ စာပေးစာယူကို စစ်ဆေးခြင်းနှင့် အီးမေးလ်ဖြင့် စစ်ထုတ်ခြင်း။

တကယ်တော့၊ တောင်းဆိုချက်သည် သောင်းနှင့်ချီသော OperativeQuestions မှတ်တမ်းများနှင့် အလုပ်လုပ်သော်လည်း အီးမေးလ်မှတစ်ဆင့် စိတ်ဝင်စားသည့်ဒေတာကိုသာ လိုအပ်ပါသည်။

OperativeQuestions စာသားကို ကြည့်ရှုသည်-

တောင်းဆိုချက် နံပါတ် ၁

 
CREATE VIEW [dbo].[OperativeQuestions]
AS
SELECT DISTINCT Q.Id, USR.email AS Email
FROM            [dbo].Questions AS Q INNER JOIN
                         [dbo].ProcessUserAccesses AS BPU ON BPU.ProcessId = CQ.Process_Id 
OUTER APPLY
                     (SELECT   1 AS HasNoObjects
                      WHERE   NOT EXISTS
                                    (SELECT   1
                                     FROM     [dbo].ObjectUserAccesses AS BOU
                                     WHERE   BOU.ProcessUserAccessId = BPU.[Id] AND BOU.[To] IS NULL)
) AS BO INNER JOIN
                         [dbo].Users AS USR ON USR.Id = BPU.UserId
WHERE        CQ.[Exp] = 0 AND CQ.AnswerId IS NULL AND BPU.[To] IS NULL 
AND (BO.HasNoObjects = 1 OR
              EXISTS (SELECT   1
                           FROM   [dbo].ObjectUserAccesses AS BOU INNER JOIN
                                      [dbo].ObjectQuestions AS QBO 
                                                  ON QBO.[Object_Id] =BOU.ObjectId
                               WHERE  BOU.ProcessUserAccessId = BPU.Id 
                               AND BOU.[To] IS NULL AND QBO.Question_Id = CQ.Id));

DbContext (EF Core 2) တွင် ကနဦးမြင်ကွင်းမြေပုံဆွဲခြင်း

public class QuestionsDbContext : DbContext
{
    //...
    public DbQuery<OperativeQuestion> OperativeQuestions { get; set; }
    //...
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Query<OperativeQuestion>().ToView("OperativeQuestions");
    }
}

ကနဦး LINQ မေးမြန်းမှု

var businessObjectsData = await context
    .OperativeQuestions
    .Where(x => x.Email == Email)
    .Include(x => x.Question)
    .Select(x => x.Question)
    .SelectMany(x => x.ObjectQuestions,
                (x, bo) => new
                {
                    Id = x.Id,
                    ObjectId = bo.Object.Id,
                    ObjectTypeId = bo.Object.ObjectType.Id,
                    ObjectTypeName = bo.Object.ObjectType.Name,
                    ObjectExternalId = bo.Object.ExternalId
                })
    .ToListAsync();

ဤကိစ္စရပ်တွင်၊ အခြေခံအဆောက်အအုံဆိုင်ရာ အပြောင်းအလဲများမရှိဘဲ အဆင်သင့်လုပ်ထားသော ရလဒ်များ (“Active Queries”) ဖြင့် သီးခြားဇယားတစ်ခုကို မိတ်ဆက်ခြင်းမပြုဘဲ၊ ၎င်းကို ဒေတာဖြည့်သွင်းရန်နှင့် ခေတ်မီစေရန်အတွက် ယန္တရားတစ်ခု လိုအပ်မည့် ဤပြဿနာအတွက် အဖြေကို ကျွန်ုပ်တို့ စဉ်းစားနေပါသည်။ .

၎င်းသည် ကောင်းမွန်သောဖြေရှင်းချက်ဖြစ်သော်လည်း ဤပြဿနာကို အကောင်းဆုံးဖြစ်အောင်ပြုလုပ်ရန် အခြားရွေးချယ်စရာတစ်ခုရှိသည်။

အဓိကရည်ရွယ်ချက်မှာ [Email] = OperativeQuestions မြင်ကွင်းမှ @p__linq__0 ဖြင့် cache entries များကို ပြုလုပ်ရန်ဖြစ်သည်။

ဇယားလုပ်ဆောင်ချက်ကို [dbo][OperativeQuestionsUserMail] ဒေတာဘေ့စ်ထဲသို့ မိတ်ဆက်ပါ။

Input Parameter အဖြစ် အီးမေးလ် ပေးပို့ခြင်းဖြင့်၊ ကျွန်ုပ်တို့သည် တန်ဖိုးများဇယားကို ပြန်လည်ရရှိသည်-

တောင်းဆိုချက် နံပါတ် ၁


CREATE FUNCTION [dbo].[OperativeQuestionsUserMail]
(
    @Email  nvarchar(4000)
)
RETURNS
@tbl TABLE
(
    [Id]           uniqueidentifier,
    [Email]      nvarchar(4000)
)
AS
BEGIN
        INSERT INTO @tbl ([Id], [Email])
        SELECT Id, @Email
        FROM [OperativeQuestions]  AS [x] WHERE [x].[Email] = @Email;
     
    RETURN;
END

၎င်းသည် ကြိုတင်သတ်မှတ်ထားသော ဒေတာဖွဲ့စည်းပုံဖြင့် တန်ဖိုးများဇယားကို ပြန်ပေးသည်။

OperativeQuestionsUserMail မှမေးမြန်းချက်များသည် အကောင်းဆုံးဖြစ်ပြီး အကောင်းဆုံးမေးမြန်းမှုအစီအစဉ်များရှိနေစေရန်အတွက်၊ တင်းကျပ်သောဖွဲ့စည်းပုံလိုအပ်သည်၊ ပြန်ပေးသည့် ဇယား...

ဤကိစ္စတွင်၊ လိုအပ်သော Query 1 ကို Query 4 အဖြစ်သို့ ပြောင်းသည်-

တောင်းဆိုချက် နံပါတ် ၁

(@p__linq__0 nvarchar(4000))SELECT
1 AS [C1],
[Extent1].[Id] AS [Id],
[Join2].[Object_Id] AS [Object_Id],
[Join2].[ObjectType_Id] AS [ObjectType_Id],
[Join2].[Name] AS [Name],
[Join2].[ExternalId] AS [ExternalId]
FROM (
    SELECT Id, Email FROM [dbo].[OperativeQuestionsUserMail] (@p__linq__0)
) AS [Extent0]
INNER JOIN [dbo].[Questions] AS [Extent1] ON([Extent0].Id=[Extent1].Id)
INNER JOIN (SELECT [Extent2].[Object_Id] AS [Object_Id], [Extent2].[Question_Id] AS [Question_Id], [Extent3].[ExternalId] AS [ExternalId], [Extent3].[ObjectType_Id] AS [ObjectType_Id], [Extent4].[Name] AS [Name]
FROM [dbo].[ObjectQuestions] AS [Extent2]
INNER JOIN [dbo].[Objects] AS [Extent3] ON [Extent2].[Object_Id] = [Extent3].[Id]
LEFT OUTER JOIN [dbo].[ObjectTypes] AS [Extent4] 
ON [Extent3].[ObjectType_Id] = [Extent4].[Id] ) AS [Join2] 
ON [Extent1].[Id] = [Join2].[Question_Id]
WHERE ([Extent1].[AnswerId] IS NULL) AND (0 = [Extent1].[Exp]);

DbContext (EF Core 2) ရှိ အမြင်များနှင့် လုပ်ဆောင်ချက်များကို ပုံဖော်ခြင်း

public class QuestionsDbContext : DbContext
{
    //...
    public DbQuery<OperativeQuestion> OperativeQuestions { get; set; }
    //...
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Query<OperativeQuestion>().ToView("OperativeQuestions");
    }
}
 
public static class FromSqlQueries
{
    public static IQueryable<OperativeQuestion> GetByUserEmail(this DbQuery<OperativeQuestion> source, string Email)
        => source.FromSql($"SELECT Id, Email FROM [dbo].[OperativeQuestionsUserMail] ({Email})");
}

နောက်ဆုံး LINQ မေးမြန်းမှု

var businessObjectsData = await context
    .OperativeQuestions
    .GetByUserEmail(Email)
    .Include(x => x.Question)
    .Select(x => x.Question)
    .SelectMany(x => x.ObjectQuestions,
                (x, bo) => new
                {
                    Id = x.Id,
                    ObjectId = bo.Object.Id,
                    ObjectTypeId = bo.Object.ObjectType.Id,
                    ObjectTypeName = bo.Object.ObjectType.Name,
                    ObjectExternalId = bo.Object.ExternalId
                })
    .ToListAsync();

လုပ်ဆောင်ချိန်၏ အစီအစဥ်သည် 200-800 ms မှ 2-20 ms သို့ ကျဆင်းသွားသည်၊ ဆိုလိုသည်မှာ အဆပေါင်း ဆယ်ဂဏန်း ပိုမြန်သည်။

ပျမ်းမျှအားဖြင့် 350 ms အစား 8 ms ကိုရရှိသည်။

သိသာထင်ရှားသော အကျိုးကျေးဇူးများမှ ကျွန်ုပ်တို့လည်း ရရှိသည်-

  1. ယေဘူယျအားဖြင့် စာဖတ်ခြင်းဝန်ကို လျှော့ချခြင်း၊
  2. ပိတ်ဆို့ခြင်း ဖြစ်နိုင်ခြေကို သိသာစွာ လျော့ကျစေပါသည်။
  3. လက်ခံနိုင်သောတန်ဖိုးများသို့ ပျမ်းမျှပိတ်ဆို့ချိန်ကို လျှော့ချပါ။

ကောက်ချက်

ဒေတာဘေ့စ်ခေါ်ဆိုမှုများကို ပိုမိုကောင်းမွန်အောင်ပြုလုပ်ခြင်းနှင့် ချိန်ညှိခြင်း MS SQL ဖြတ်. လင့်ခ် ဖြေရှင်းလို့ရတဲ့ ပြဿနာတစ်ခုပါ။

ဤလုပ်ငန်းတွင် အာရုံစူးစိုက်မှုနှင့် လိုက်လျောညီထွေရှိမှုသည် အလွန်အရေးကြီးပါသည်။

လုပ်ငန်းစဉ်အစတွင်-

  1. တောင်းဆိုမှုအလုပ်လုပ်သည့်ဒေတာ (တန်ဖိုးများ၊ ရွေးချယ်ထားသောဒေတာအမျိုးအစားများ) ကိုစစ်ဆေးရန်လိုအပ်သည်
  2. ဤအချက်အလက်ကို မှန်ကန်သော အညွှန်းကိန်းပြုလုပ်ပါ။
  3. ဇယားများကြားတွင် ပါဝင်နေသည့် အခြေအနေများ၏ မှန်ကန်မှုကို စစ်ဆေးပါ။

နောက်ထပ် ပိုမိုကောင်းမွန်အောင် ပြုလုပ်ခြင်း ထပ်ခါထပ်ခါ ဖော်ပြသည်-

  1. တောင်းဆိုချက်၏အခြေခံနှင့် ပင်မတောင်းဆိုမှု စစ်ထုတ်မှုကို သတ်မှတ်သည်။
  2. အလားတူမေးမြန်းမှုတုံးများကို ထပ်ခါတလဲလဲပြုလုပ်ပြီး အခြေအနေများ၏ လမ်းဆုံကို ပိုင်းခြားစိတ်ဖြာခြင်း။
  3. SSMS သို့မဟုတ် အခြား GUI များအတွက် SQL Server သူ့ဟာသူ optimizes SQL မေးမြန်းမှု (အလယ်အလတ်ဒေတာသိုလှောင်မှုကို ခွဲဝေချထားပေးခြင်း၊ ဤသိုလှောင်မှုအား အသုံးပြု၍ ရလဒ်မေးမြန်းမှုကို တည်ဆောက်ခြင်း (အများအပြားရှိနိုင်သည်))
  4. နောက်ဆုံးအဆင့်တွင် ရလဒ်ကို အခြေခံအဖြစ် ယူသည်။ SQL မေးမြန်းမှုဖွဲ့စည်းပုံကို ပြန်လည်တည်ဆောက်နေပါတယ်။ LINQ မေးမြန်းမှု

ရလာတဲ့ရလဒ် LINQ မေးမြန်းမှု ဖော်ထုတ်ထားသော အကောင်းမွန်ဆုံးနှင့် ဖွဲ့စည်းပုံတွင် ထပ်တူထပ်မျှ ဖြစ်သင့်သည်။ SQL မေးမြန်းမှု အမှတ် ၃ မှ

ကျေးဇူးတင်လွှာ

လုပ်ဖော်ကိုင်ဖက်တွေကို ကျေးဇူးအများကြီးတင်ပါတယ်။ jobgemws и alex_ozr ကုမ္ပဏီထံမှ Fortis ဤပစ္စည်းကို ပြင်ဆင်ရာတွင် အထောက်အကူဖြစ်စေရန်။

source: www.habr.com

မှတ်ချက် Add