Ich habe zwei Tabellen, in denen ich speichere:
- eine IP-Bereich - Länder-Nachschlagetabelle
- Eine Liste der Anforderungen, die von verschiedenen IPs stammen
Die IPs wurden als bigints gespeichert , um die Suchleistung zu verbessern.
Dies ist die Tabellenstruktur:
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
)
Ich möchte die Aufschlüsselung der Anfragen nach Ländern erhalten, daher führe ich die folgende Abfrage durch:
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
Ich habe viele Datensätze in den Tabellen: ungefähr 200.000 Zoll IP2Countryund einige Millionen Zoll Request, daher dauert die Abfrage eine Weile.
Mit Blick auf den Ausführungsplan ist der teuerste Teil ein Clustered Index Seek für den Index PK_IP2Country, der viele Male ausgeführt wird (die Anzahl der Zeilen in Request).
Außerdem ist etwas, bei dem ich mich etwas seltsam fühle, der left join ip2country ic on r.IP between ic.begin_num and ic.end_numTeil (ich weiß nicht, ob es einen besseren Weg gibt, die Suche durchzuführen).
Die Tabellenstruktur, einige Beispieldaten und die Abfrage sind in SQLFiddle verfügbar: http://www.sqlfiddle.com/#!3/a463e/3 (leider glaube ich nicht, dass ich viele Datensätze einfügen kann, um das Problem zu reproduzieren, aber dies hoffentlich gibt eine Idee).
Ich bin (offensichtlich) kein Experte für SQL-Leistung / -Optimierungen, daher lautet meine Frage: Gibt es offensichtliche Möglichkeiten, wie diese Struktur / Abfrage in Bezug auf die Leistung verbessert werden kann, die mir fehlen?
begin_ipund end_ipbeizubehalten, um zu verhindern, dass Text und Zahlen irgendwie nicht mehr synchron sind.
ip2country (begin_num, end_num)?
give me the first record that has a begin_num < ip in asc order of begin_num(korrigieren Sie mich, wenn ich falsch liege ) gültig sein und die Leistung verbessern könnte.
begin_numnach end_numdiesem Satz scannt , dann innerhalb dieses Satzes nach ihm scannt und nur einen Datensatz findet.
begin_num. Ich muss auchA BETWEEN B AND Cziemlich oft mitmachen , und ich bin gespannt, ob es einen Weg gibt, dies ohne langwierige RBAR-Beitritte zu erreichen.