प्रश्न का मूल "LINQ के साथ ऑर्डर क्यों मायने रखता है?" नहीं है। LINQ बिना किसी क्रम के शाब्दिक अनुवाद करता है। असली सवाल यह है कि "दो SQL क्वेरीज़ का प्रदर्शन अलग-अलग क्यों है?"।
मैं केवल 100k पंक्तियों को सम्मिलित करके समस्या को पुन:उत्पन्न करने में सक्षम था। उस स्थिति में ऑप्टिमाइज़र में एक कमजोरी शुरू हो रही है:यह नहीं पहचानता है कि यह Colour
पर एक खोज कर सकता है जटिल स्थिति के कारण। पहली क्वेरी में ऑप्टिमाइज़र पैटर्न को पहचानता है और एक इंडेक्स सीक बनाता है।
ऐसा क्यों होना चाहिए इसका कोई अर्थपूर्ण कारण नहीं है। NULL
. पर खोज करने पर भी अनुक्रमणिका पर खोज संभव है . यह अनुकूलक में एक कमजोरी/बग है। ये रहे दो प्लान:
ईएफ यहां मददगार होने की कोशिश करता है क्योंकि यह मानता है कि कॉलम और फिल्टर वैरिएबल दोनों शून्य हो सकते हैं। उस स्थिति में यह आपको एक मैच देने की कोशिश करता है (जो कि C# शब्दार्थ के अनुसार सही बात है)।
मैंने निम्न फ़िल्टर जोड़कर इसे पूर्ववत करने का प्रयास किया:
Colour IS NOT NULL AND @p__linq__0 IS NOT NULL
AND Size IS NOT NULL AND @p__linq__1 IS NOT NULL
आशा है कि अनुकूलक अब उस ज्ञान का उपयोग जटिल EF फ़िल्टर व्यंजक को सरल बनाने के लिए करता है। यह ऐसा करने में कामयाब नहीं हुआ। यदि यह काम करता तो वही फ़िल्टर ईएफ क्वेरी में जोड़ा जा सकता था जो एक आसान समाधान प्रदान करता है।
यहाँ वे सुधार दिए गए हैं जिनकी मैं अनुशंसा करता हूँ ताकि आप उन्हें आज़माएँ:
- डेटाबेस में डेटाबेस कॉलम को नॉट-नल बनाएं
- ईएफ डेटा मॉडल में कॉलम को नॉट-नल बनाएं, इस उम्मीद में कि यह ईएफ को जटिल फिल्टर स्थिति बनाने से रोकेगा
- अनुक्रमणिका बनाएं:
Colour, Size
और/याSize, Colour
. वे उनकी समस्या भी दूर करते हैं। - सुनिश्चित करें कि फ़िल्टरिंग सही क्रम में की गई है और एक कोड टिप्पणी छोड़ दें
INTERSECT
का उपयोग करने का प्रयास करें /Queryable.Intersect
फिल्टर गठबंधन करने के लिए। इसका परिणाम अक्सर अलग-अलग योजना आकार में होता है।- एक इनलाइन तालिका-मूल्यवान फ़ंक्शन बनाएं जो फ़िल्टरिंग करता है। EF ऐसे फ़ंक्शन का उपयोग एक बड़ी क्वेरी के भाग के रूप में कर सकता है
- कच्ची SQL पर ड्रॉप डाउन करें
- योजना बदलने के लिए योजना मार्गदर्शिका का उपयोग करें
ये सभी समाधान हैं, मूल कारण समाधान नहीं हैं।
अंत में मैं यहाँ SQL सर्वर और EF दोनों से खुश नहीं हूँ। दोनों उत्पादों को ठीक किया जाना चाहिए। काश, वे शायद नहीं होते और आप उसके लिए भी इंतजार नहीं कर सकते।
यहाँ अनुक्रमणिका स्क्रिप्ट हैं:
CREATE NONCLUSTERED INDEX IX_Widget_Colour_Size ON dbo.Widget
(
Colour, Size
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE NONCLUSTERED INDEX IX_Widget_Size_Colour ON dbo.Widget
(
Size, Colour
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]