TSQL 性能 - 加入最小值和最大值之间的值

Cri*_*scu 10 performance sql-server-2008 t-sql query-performance

我有两张表用于存储:

  • IP 范围 - 国家/地区查找表
  • 来自不同 IP 的请求列表

IP 存储为bigints 以提高查找性能。

这是表结构:

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
)
Run Code Online (Sandbox Code Playgroud)

我想获取每个国家/地区的请求细分,因此我执行以下查询:

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
Run Code Online (Sandbox Code Playgroud)

我在表中有很多记录:大约 200,000 条记录IP2Country和几百万条记录Request,因此查询需要一段时间。

查看执行计划,开销最大的部分是对索引 PK_IP2Country 的 Clustered Index Seek,它执行了很多次(Request 中的行数)。

另外,我觉得有点奇怪的是left join ip2country ic on r.IP between ic.begin_num and ic.end_num部分(不知道是否有更好的方法来执行查找)。

SQLFiddle 中提供了表结构、一些示例数据和查询:http ://www.sqlfiddle.com/#!3 / a463e /3(不幸的是,我认为我不能插入很多记录来重现问题,但这希望给出一个想法)。

我(显然)不是 SQL 性能/优化方面的专家,所以我的问题是:是否有任何明显的方法可以提高我缺少的结构/查询的性能?

JNK*_*JNK 3

您需要一个额外的索引。 在你的小提琴示例中我添加了:

CREATE UNIQUE INDEX ix_IP ON Request(CategoryID, IP)

它涵盖了您对表的请求并获取索引查找而不是聚集索引扫描。

看看如何改进并告诉我。我猜这会有很大帮助,因为对该索引的扫描我确信并不便宜。