SQL INNER JOIN va boshqalar

Tasavvur qilaylik, menda mijozdan yuborilgan magistrallar ro'yxati mavjud. Va moslik mintaqalari nomli jadvalim bor. Agar nom xususiyatiga ega bo'lgan qatorlarni qidirmoqchi bo'lsangiz va mintaqadagi elementlar satrda bo'lishi kerak.

LINQ'da men uni ikki xil usulda qila olaman. Quyidagi kabi ikkita SQL so'rovi ishlab chiqariladi. Mening savolim qaysi birini tanlashim kerak? Qaysi so'rov yaxshi ishlashga ega?

 List regions = new List() { "Canada", "EN 50530" };

           var cregions = from c in complianceRegions
                           from r in regions
                           where c.Name.Equals(r)
                           select c;

            var cregions2 = from c in complianceRegions
                            where regions.Any(x => x == c.Name)
                            select c;

Yaratilgan SQL quyida ko'rsatilgan.

      -- cregions
   SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[Description] AS [Description]
    FROM  [Administration].[ComplianceRegions] AS [Extent1]
    INNER JOIN  (SELECT 
        N'Canada' AS [C1]
        FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
    UNION ALL
        SELECT 
        N'EN 50530' AS [C1]
        FROM  ( SELECT 1 AS X ) AS [SingleRowTable2]) AS [UnionAll1] ON [Extent1].[Name] = [UnionAll1].[C1]  

cregions

Va

--cregions2
    SELECT 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[Description] AS [Description]
    FROM [Administration].[ComplianceRegions] AS [Extent1]
    WHERE  EXISTS (SELECT 
        1 AS [C1]
        FROM  (SELECT 
            N'Canada' AS [C1]
            FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
        UNION ALL
            SELECT 
            N'EN 50530' AS [C1]
            FROM  ( SELECT 1 AS X ) AS [SingleRowTable2]) AS [UnionAll1]
        WHERE [UnionAll1].[C1] = [Extent1].[Name]
    )

cregions2 Added Execution plan as requested.

5
Ok, u holda sizning 3-optioinangiz - "code" ning "c" kodidan "joylar" joylashgan hududlarda joylashgan. "C" (c.Name) ni tanlaymiz, u @Gordon tomonidan aytilgan SQLni yaratadi va IMO sizning joriy savolingizni bekor qilishi kerak CROSS JOIN yoki EXISTS nima bo'ladi :)
qo'shib qo'ydi muallif Ivan Stoev, manba
Ok, u holda sizning 3-optioinangiz - "code" ning "c" kodidan "joylar" joylashgan hududlarda joylashgan. "C" (c.Name) ni tanlaymiz, u @Gordon tomonidan aytilgan SQLni yaratadi va IMO sizning joriy savolingizni bekor qilishi kerak CROSS JOIN yoki EXISTS nima bo'ladi :)
qo'shib qo'ydi muallif Ivan Stoev, manba
Ok, u holda sizning 3-optioinangiz - "code" ning "c" kodidan "joylar" joylashgan hududlarda joylashgan. "C" (c.Name) ni tanlaymiz, u @Gordon tomonidan aytilgan SQLni yaratadi va IMO sizning joriy savolingizni bekor qilishi kerak CROSS JOIN yoki EXISTS nima bo'ladi :)
qo'shib qo'ydi muallif Ivan Stoev, manba
Birinchi so'rov nima uchun o'z ichiga oladi va ikkinchi == ishlatadi? Ko'rsatilgan taqqoslash operatori qaysi? Hozir siz olma apelsinlar bilan taqqoslanasiz.
qo'shib qo'ydi muallif Ivan Stoev, manba
Birinchi so'rov nima uchun o'z ichiga oladi va ikkinchi == ishlatadi? Ko'rsatilgan taqqoslash operatori qaysi? Hozir siz olma apelsinlar bilan taqqoslanasiz.
qo'shib qo'ydi muallif Ivan Stoev, manba
Qaysi so'rov yaxshi ishlashga ega? O'zingizning testlaringiz nimani ochib berdi?
qo'shib qo'ydi muallif High Performance Mark, manba
@IvanStoev Iltimos, hozir tekshiring. rahmat.
qo'shib qo'ydi muallif Foyzul Karim, manba
@IvanStoev Iltimos, hozir tekshiring. rahmat.
qo'shib qo'ydi muallif Foyzul Karim, manba
@IvanStoev Iltimos, hozir tekshiring. rahmat.
qo'shib qo'ydi muallif Foyzul Karim, manba
Uzr. savolni tegishli so'rov bilan yangilash. @IvanStoev
qo'shib qo'ydi muallif Foyzul Karim, manba
Uzr. savolni tegishli so'rov bilan yangilash. @IvanStoev
qo'shib qo'ydi muallif Foyzul Karim, manba
qiziq bir qismi, men bir xil so'rovni bir necha marta ishlatganimda, SQL server so'rovni keshlashi va menga noto'g'ri ishlashni berishidir.
qo'shib qo'ydi muallif Foyzul Karim, manba
qiziq bir qismi, men bir xil so'rovni bir necha marta ishlatganimda, SQL server so'rovni keshlashi va menga noto'g'ri ishlashni berishidir.
qo'shib qo'ydi muallif Foyzul Karim, manba

7 javoblar

Ikki muqobilni hisobga olgan holda, ikkinchisi yaxshi bo'lishi mumkin, chunki ustun nomida hech qanday funktsiya chaqiruvi mavjud emas.

Biroq, bu ikkisi bir xil emas. Birinchisi qisman o'yin bo'lib, ikkinchisi esa aniq o'yin. Siz, albatta, xohlagan narsani qilmog'ingiz kerak. Ishlash aniqlikka ikkinchi darajali.

Ikkalasi ham og'riqli ko'rinishga ega. CHARINDEX() ning chiqishini indeksga uzatish? Biz "ortiqcha" deb ayta olamizmi?

So'rovlar nima uchun oddiygina emas, degan savolni so'rashadi:

select . . .
from [Administration].[ComplianceRegions] AS [Extent1]
where Extent1.Name in (N'Canada', N'EN 50530');

Ushbu mantiqning eng sodda va eng yaxshi versiyasi.

2
qo'shib qo'ydi
@IvanStoev. . . Ehtimol, siz ushbu ma'lumot bilan javob berishingiz kerak. Men linqni ishlatmayman, shuning uchun bunday tavsiyani qilish noqulay.
qo'shib qo'ydi muallif Gordon Linoff, manba
@IvanStoev. . . Juda yaxshi nuqta. Ikkinchisi esa to'liq mos keladi. OP o'uv rejasini tanlashi kerak.
qo'shib qo'ydi muallif Gordon Linoff, manba
@GordonLinoff Men faqat (birinchi navbatda birinchi so'rovga qarab) buni ko'rganman. Ha, agar ikkinchi OP talab qiladigan bo'lsa, uni Enumerable.Contains yordamida yozishingiz mumkin va siz so'zlagan SQL kodiga aylantiriladi.
qo'shib qo'ydi muallif Ivan Stoev, manba
nima uchun so'rov oddiygina emas ... chunki u qisman o'yinni qidirmoqda?
qo'shib qo'ydi muallif Ivan Stoev, manba
@FoyzulKarim: Siz ikkala so'rov va diagrammaning ijro rejalarini joylashtirishingiz kerak, shu bilan bog'liq jadvallarni hisoblashingiz mumkin. Bu bilan bu savolga javob berilmaydi
qo'shib qo'ydi muallif TheGameiswar, manba
@GordonLinoff Iltimos, yangilangan savolni tekshiring. Rahmat.
qo'shib qo'ydi muallif Foyzul Karim, manba
@TheGameiswar Iltimos, yangilangan savolni tekshiring. Rahmat.
qo'shib qo'ydi muallif Foyzul Karim, manba
ok. savollarni yangilash. Mr. @thegameiswar ni tekshiring
qo'shib qo'ydi muallif Foyzul Karim, manba
ammo bu so'rovlar avtomatik tarzda yaratiladi. Yaxshi LINQ so'rovini tanlash kerak.
qo'shib qo'ydi muallif Foyzul Karim, manba

Ikki muqobilni hisobga olgan holda, ikkinchisi yaxshi bo'lishi mumkin, chunki ustun nomida hech qanday funktsiya chaqiruvi mavjud emas.

Biroq, bu ikkisi bir xil emas. Birinchisi qisman o'yin bo'lib, ikkinchisi esa aniq o'yin. Siz, albatta, xohlagan narsani qilmog'ingiz kerak. Ishlash aniqlikka ikkinchi darajali.

Ikkalasi ham og'riqli ko'rinishga ega. CHARINDEX() ning chiqishini indeksga uzatish? Biz "ortiqcha" deb ayta olamizmi?

So'rovlar nima uchun oddiygina emas, degan savolni so'rashadi:

select . . .
from [Administration].[ComplianceRegions] AS [Extent1]
where Extent1.Name in (N'Canada', N'EN 50530');

Ushbu mantiqning eng sodda va eng yaxshi versiyasi.

2
qo'shib qo'ydi
@IvanStoev. . . Ehtimol, siz ushbu ma'lumot bilan javob berishingiz kerak. Men linqni ishlatmayman, shuning uchun bunday tavsiyani qilish noqulay.
qo'shib qo'ydi muallif Gordon Linoff, manba
@IvanStoev. . . Juda yaxshi nuqta. Ikkinchisi esa to'liq mos keladi. OP o'uv rejasini tanlashi kerak.
qo'shib qo'ydi muallif Gordon Linoff, manba
nima uchun so'rov oddiygina emas ... chunki u qisman o'yinni qidirmoqda?
qo'shib qo'ydi muallif Ivan Stoev, manba
@GordonLinoff Men faqat (birinchi navbatda birinchi so'rovga qarab) buni ko'rganman. Ha, agar ikkinchi OP talab qiladigan bo'lsa, uni Enumerable.Contains yordamida yozishingiz mumkin va siz so'zlagan SQL kodiga aylantiriladi.
qo'shib qo'ydi muallif Ivan Stoev, manba
@FoyzulKarim: Siz ikkala so'rov va diagrammaning ijro rejalarini joylashtirishingiz kerak, shu bilan bog'liq jadvallarni hisoblashingiz mumkin. Bu bilan bu savolga javob berilmaydi
qo'shib qo'ydi muallif TheGameiswar, manba
@GordonLinoff Iltimos, yangilangan savolni tekshiring. Rahmat.
qo'shib qo'ydi muallif Foyzul Karim, manba
@TheGameiswar Iltimos, yangilangan savolni tekshiring. Rahmat.
qo'shib qo'ydi muallif Foyzul Karim, manba
ok. savollarni yangilash. Mr. @thegameiswar ni tekshiring
qo'shib qo'ydi muallif Foyzul Karim, manba
ammo bu so'rovlar avtomatik tarzda yaratiladi. Yaxshi LINQ so'rovini tanlash kerak.
qo'shib qo'ydi muallif Foyzul Karim, manba

Ikki muqobilni hisobga olgan holda, ikkinchisi yaxshi bo'lishi mumkin, chunki ustun nomida hech qanday funktsiya chaqiruvi mavjud emas.

Biroq, bu ikkisi bir xil emas. Birinchisi qisman o'yin bo'lib, ikkinchisi esa aniq o'yin. Siz, albatta, xohlagan narsani qilmog'ingiz kerak. Ishlash aniqlikka ikkinchi darajali.

Ikkalasi ham og'riqli ko'rinishga ega. CHARINDEX() ning chiqishini indeksga uzatish? Biz "ortiqcha" deb ayta olamizmi?

So'rovlar nima uchun oddiygina emas, degan savolni so'rashadi:

select . . .
from [Administration].[ComplianceRegions] AS [Extent1]
where Extent1.Name in (N'Canada', N'EN 50530');

Ushbu mantiqning eng sodda va eng yaxshi versiyasi.

2
qo'shib qo'ydi
@IvanStoev. . . Juda yaxshi nuqta. Ikkinchisi esa to'liq mos keladi. OP o'uv rejasini tanlashi kerak.
qo'shib qo'ydi muallif Gordon Linoff, manba
@IvanStoev. . . Ehtimol, siz ushbu ma'lumot bilan javob berishingiz kerak. Men linqni ishlatmayman, shuning uchun bunday tavsiyani qilish noqulay.
qo'shib qo'ydi muallif Gordon Linoff, manba
@GordonLinoff Men faqat (birinchi navbatda birinchi so'rovga qarab) buni ko'rganman. Ha, agar ikkinchi OP talab qiladigan bo'lsa, uni Enumerable.Contains yordamida yozishingiz mumkin va siz so'zlagan SQL kodiga aylantiriladi.
qo'shib qo'ydi muallif Ivan Stoev, manba
nima uchun so'rov oddiygina emas ... chunki u qisman o'yinni qidirmoqda?
qo'shib qo'ydi muallif Ivan Stoev, manba
@FoyzulKarim: Siz ikkala so'rov va diagrammaning ijro rejalarini joylashtirishingiz kerak, shu bilan bog'liq jadvallarni hisoblashingiz mumkin. Bu bilan bu savolga javob berilmaydi
qo'shib qo'ydi muallif TheGameiswar, manba
@TheGameiswar Iltimos, yangilangan savolni tekshiring. Rahmat.
qo'shib qo'ydi muallif Foyzul Karim, manba
@GordonLinoff Iltimos, yangilangan savolni tekshiring. Rahmat.
qo'shib qo'ydi muallif Foyzul Karim, manba
ok. savollarni yangilash. Mr. @thegameiswar ni tekshiring
qo'shib qo'ydi muallif Foyzul Karim, manba
ammo bu so'rovlar avtomatik tarzda yaratiladi. Yaxshi LINQ so'rovini tanlash kerak.
qo'shib qo'ydi muallif Foyzul Karim, manba

Ushbu so'rovlar tengdir. Ikkalasi ham dahshatli, ulardan hech birini tanlamagan bo'lardim. Ular qattiq kodli qadriyatlarga ega, shuning uchun ularni qayta ishlatish mumkin emas.SQL-serverautoparametrizatsiyasi bilan shug'ullanishi mumkinligiga ishonchim komil emas, shuning uchun ijro rejasining keshi ehtimol zarar ko'radi. To'g'ri yechim stol qiymatlari parametrlaridan foydalanadi, afsuski ular bilishimcha linq provayderlarida qo'llab-quvvatlanmaydi. Demak, so'rovni o'zingiz qilishingiz kerak, natijada siz natijani bajarish uchun faqat linqdan foydalanishingiz mumkin.

Siz Ivan Stoev tomonidan taqdim etilgan yechimni sinab ko'rishingiz mumkin, bu sizning provayderingiz ishlab chiqaradigan mahsulotga qanchalik yaxshi bog'liq. Linq2sql uzoqroq ro'yxat uchun yaxshiroq emas, chunki sizda mavjud bo'lgan ro'yxatdagi ko'plab parametrlarni ishlab chiqaradi. Ro'yxatdagi elementlarning soni bir xil bo'lsa, hech bo'lmaganda bajarish rejasini qayta ishlatishi mumkin.

0
qo'shib qo'ydi

Ushbu so'rovlar tengdir. Ikkalasi ham dahshatli, ulardan hech birini tanlamagan bo'lardim. Ular qattiq kodli qadriyatlarga ega, shuning uchun ularni qayta ishlatish mumkin emas.SQL-serverautoparametrizatsiyasi bilan shug'ullanishi mumkinligiga ishonchim komil emas, shuning uchun ijro rejasining keshi ehtimol zarar ko'radi. To'g'ri yechim stol qiymatlari parametrlaridan foydalanadi, afsuski ular bilishimcha linq provayderlarida qo'llab-quvvatlanmaydi. Demak, so'rovni o'zingiz qilishingiz kerak, natijada siz natijani bajarish uchun faqat linqdan foydalanishingiz mumkin.

Siz Ivan Stoev tomonidan taqdim etilgan yechimni sinab ko'rishingiz mumkin, bu sizning provayderingiz ishlab chiqaradigan mahsulotga qanchalik yaxshi bog'liq. Linq2sql uzoqroq ro'yxat uchun yaxshiroq emas, chunki sizda mavjud bo'lgan ro'yxatdagi ko'plab parametrlarni ishlab chiqaradi. Ro'yxatdagi elementlarning soni bir xil bo'lsa, hech bo'lmaganda bajarish rejasini qayta ishlatishi mumkin.

0
qo'shib qo'ydi

@ JNK takliflari bu yozuvda javob beradi.

EXISTS boolean qiymatini qaytarish uchun ishlatiladi, JOIN boshqa jadvalni qaytaradi

EXISTS faqat pastki so'rov natijalari va qisqa kontaktlarning zanglashiga olib kelishini tekshirish uchun ishlatiladi. JOIN, unga bog'liq bo'lgan boshqa jadvaldagi qo'shimcha joylar bilan uni birlashtirish yo'li bilan natijalarni kengaytirish uchun ishlatiladi.

Sizning namunangizda so'rovlar o'zaro o'xshashdir.

Umuman olganda, EXISTS dan foydalaning:

Tegishli jadvaldan ma'lumotlarni qaytarib olishingiz shart emas Tegishli jadvalda dublar mavjud (JOIN qiymatlari takrorlangan bo'lsa, ikki nusxadagi satrlarni keltirishi mumkin) Siz mavjudlikni tekshirishni xohlaysiz (LEFT OUTTER JOIN ... NULL holatidan foydalaning) Kerakli ko'rsatkichlarga ega bo'lsangiz, EXISTS ko'pincha JOIN bilan bir xil tarzda ishlaydi. Istisno EXISTS dan foydalanishning ancha murakkab bo'lgan pastki so'rovlarida.

JOIN tugmachasi indekslanmagan bo'lsa, EXISTS dan foydalanish tezroq bo'lishi mumkin, ammo siz o'zingizning aniq holatingizni tekshirishingiz kerak bo'ladi.

JOIN sintaksisi odatdagi o'qish va aniqroq o'qishni osonlashtiradi.

0
qo'shib qo'ydi

@ JNK takliflari bu yozuvda javob beradi.

EXISTS boolean qiymatini qaytarish uchun ishlatiladi, JOIN boshqa jadvalni qaytaradi

EXISTS faqat pastki so'rov natijalari va qisqa kontaktlarning zanglashiga olib kelishini tekshirish uchun ishlatiladi. JOIN, unga bog'liq bo'lgan boshqa jadvaldagi qo'shimcha joylar bilan uni birlashtirish yo'li bilan natijalarni kengaytirish uchun ishlatiladi.

Sizning namunangizda so'rovlar o'zaro o'xshashdir.

Umuman olganda, EXISTS dan foydalaning:

Tegishli jadvaldan ma'lumotlarni qaytarib olishingiz shart emas Tegishli jadvalda dublar mavjud (JOIN qiymatlari takrorlangan bo'lsa, ikki nusxadagi satrlarni keltirishi mumkin) Siz mavjudlikni tekshirishni xohlaysiz (LEFT OUTTER JOIN ... NULL holatidan foydalaning) Kerakli ko'rsatkichlarga ega bo'lsangiz, EXISTS ko'pincha JOIN bilan bir xil tarzda ishlaydi. Istisno EXISTS dan foydalanishning ancha murakkab bo'lgan pastki so'rovlarida.

JOIN tugmachasi indekslanmagan bo'lsa, EXISTS dan foydalanish tezroq bo'lishi mumkin, ammo siz o'zingizning aniq holatingizni tekshirishingiz kerak bo'ladi.

JOIN sintaksisi odatdagi o'qish va aniqroq o'qishni osonlashtiradi.

0
qo'shib qo'ydi