Ash*_*ish 6 index sql-server-2000
我有一个简单的查询和表,我想知道哪种索引对这种表和查询是有效的。
在我的表中,我有 3 列
CREATE TABLE mYTable(ipFrom BIGINT, ipto BIGINT, url NVARCHAR(255))
Run Code Online (Sandbox Code Playgroud)
我正在运行这个简单的查询。
SELECT url
FROM MyTable
WHERE ipto <= somevalue AND ipfrom >= somevalue
Run Code Online (Sandbox Code Playgroud)
我还在所有 3 列上创建了索引,这些列聚集在 ipFrom 上,其余 2 列上没有聚集。但是这个查询在 CPU 和读取方面给我带来了非常糟糕的性能。
有什么建议。
我实施的是我喜欢根据 IP 地址重定向用户。我存储了来自不同地区和州的多个 IP 范围,并根据用户的 IP 将用户重定向到适当的 URL。
是的,我认为我在两列中以错误的方式插入了数据(稍后会重命名列),但这里的重点是最小化 CPU。
当我查看那里的执行计划时,它会在 where 子句中转换数据,我不知道它为什么要在 where 子句中转换数据。有这样的事情
|--聚簇索引查找(OBJECT:([T].[TC]), SEEK:([T].[C] > Convert([@V])
根据马丁的评论,我假设问题中有一个错字。
与单一范围的问题上寻求要么ipFrom或者ipTo是平均起来将需要寻求一半表。另一种方法是
1)添加一个计算列,例如:
ALTER TABLE MyTable
ADD granule
AS CASE WHEN (ipTo-ipFrom)<16 THEN 1 WHEN (ipTo-ipFrom)<256 THEN 2 ELSE 3 END;
Run Code Online (Sandbox Code Playgroud)
2) 索引计算列和 ipFrom
CREATE ClUSTERED INDEX IX ON MyTable(granule, ipFrom );
Run Code Online (Sandbox Code Playgroud)
3)这样的查询:
SELECT url
FROM MyTable
WHERE granule = 1
AND ipFrom BETWEEN @somevalue - 16 AND @somevalue
AND ipTo >= @somevalue
UNION ALL
SELECT url
FROM MyTable
WHERE granule = 2
AND ipFrom BETWEEN @somevalue - 256 AND @somevalue
AND ipTo >= @somevalue
UNION ALL
SELECT url
FROM MyTable
WHERE granule = 3
AND ipFrom <= @somevalue
AND ipTo >= @somevalue;
Run Code Online (Sandbox Code Playgroud)
确切地说,您如何定义“颗粒”函数将取决于ipto-ipfrom数据中的传播速度。
这符合您当前的逻辑(未经测试),但请参阅我对问题的评论。
我所做的是反转过滤器以排除不需要的行:现在您可以索引ipto和ipfrom(当然,索引中也需要 url,除非您有可以替代的 PK)
我建议 SQL Server 2005+ 使用此方法
SELECT url
FROM MyTable
EXCEPT
SELECT url
FROM MyTable
WHERE ipto > somevalue
EXCEPT
SELECT url
FROM MyTable
WHERE ipfrom < somevalue
Run Code Online (Sandbox Code Playgroud)
但是,对于 SQL Server 2000
SELECT url
FROM MyTable M
WHERE
NOT EXISTS (SELECT *
FROM MyTable M2
WHERE ipto > somevalue AND M.url = M2.url)
AND
NOT EXISTS (SELECT *
FROM MyTable M3
WHERE pfrom < somevalue AND M.url = M3.url)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1225 次 |
| 最近记录: |