मेरे पास दो टेबल हैं जिनमें मैं स्टोर करता हूं:
- एक आईपी रेंज - देश लुकअप टेबल
- विभिन्न आईपी से आने वाले अनुरोधों की एक सूची
IP bigint
लुकअप प्रदर्शन को बेहतर बनाने के लिए संग्रहीत किए गए थे ।
यह तालिका संरचना है:
create table [dbo].[ip2country](
[begin_ip] [varchar](15) NOT NULL,
[end_ip] [varchar](15) NOT NULL,
[begin_num] [bigint] NOT NULL,
[end_num] [bigint] NOT NULL,
[IDCountry] [int] NULL,
constraint [PK_ip2country] PRIMARY KEY CLUSTERED
(
[begin_num] ASC,
[end_num] ASC
)
)
create table Request(
Id int identity primary key,
[Date] datetime,
IP bigint,
CategoryId int
)
मैं प्रति देश अनुरोध विराम प्राप्त करना चाहता हूं, इसलिए मैं निम्नलिखित प्रश्न करता हूं:
select
ic.IDCountry,
count(r.Id) as CountryCount
from Request r
left join ip2country ic
on r.IP between ic.begin_num and ic.end_num
where r.CategoryId = 1
group by ic.IDCountry
मेरे पास तालिकाओं में बहुत सारे रिकॉर्ड हैं: लगभग 200,000 IP2Country
और कुछ लाखों में Request
, इसलिए क्वेरी में कुछ समय लगता है।
निष्पादन योजना को देखते हुए, सबसे महंगा हिस्सा सूचकांक PK_IP2Country पर एक क्लस्टर इंडेक्स सीक है, जिसे कई बार निष्पादित किया जाता है (अनुरोध में पंक्तियों की संख्या)।
इसके अलावा, कुछ ऐसा है जो मुझे थोड़ा अजीब लगता है, वह left join ip2country ic on r.IP between ic.begin_num and ic.end_num
हिस्सा है (पता नहीं है कि लुकअप करने का कोई बेहतर तरीका है)।
तालिका संरचना, कुछ नमूना डेटा और क्वेरी SQLFiddle में उपलब्ध हैं: http://www.sqlfiddle.com/#/3/a463e/3 (दुर्भाग्य से मुझे नहीं लगता कि मैं समस्या को पुन: उत्पन्न करने के लिए कई रिकॉर्ड सम्मिलित कर सकता हूं, लेकिन यह उम्मीद है कि एक विचार देता है)।
मैं (स्पष्ट रूप से) एसक्यूएल प्रदर्शन / अनुकूलन में विशेषज्ञ नहीं हूं, इसलिए मेरा सवाल है: क्या कोई स्पष्ट तरीके हैं जिससे इस संरचना / क्वेरी को प्रदर्शन-वार बेहतर बनाया जा सकता है कि मैं गायब हूं?
begin_ip
और end_ip
बनाए रखने पर विचार करूंगा ।
ip2country (begin_num, end_num)
?
give me the first record that has a begin_num < ip in asc order of begin_num
(मुझे सही है तो गलत है) मान्य हो सकता है और प्रदर्शन में सुधार कर सकता है।
begin_num
, फिर end_num
उस सेट के भीतर स्कैन करता है और केवल एक रिकॉर्ड पाता है।
begin_num
। मुझे भीA BETWEEN B AND C
अक्सर इसमें शामिल होना पड़ता है , और मुझे यह जानने की उत्सुकता है कि क्या थकाऊ आरबीएआर जॉइन के बिना इसे प्राप्त करने का कोई तरीका है।