【问题标题】:Querying Sql server with index for range使用范围索引查询 Sql 服务器
【发布时间】:2013-10-08 19:29:12
【问题描述】:

我正在使用在 windows datacenter 2012 上运行的 SQL SERVER 2012,

我有一个数据库,其中包含如下构建的表:

[ID] (pk,int not null)
[Start] (float,null)
[End] (float, null)
[CID] (int,null) --country id

我有一个获取 IP 的网络服务,将其转换为十进制 (可以参考这个:IP address conversion to decimal and vice versa)并向数据库服务器请求国家/地区ID

首先提到的表格包含约 200K 行,其中开始和结束值表示 IP 范围(十进制)以及与每个范围相关的 countryid,

在处理一些繁重的流量时,我遇到了非常高的 CPU 使用率,所以我在开始列和结束列上添加了索引,之后 CPU 变得更好了一点,但我认为它应该更多,它的只是假设在排序列表中搜索应该非常快,尽管我添加索引的预期结果与现实相去甚远,

我想这是因为它不是搜索列表而是搜索范围

什么是有效处理这种情况的最佳方法,因为我确信这个简单的操作占用我的资源比它应该的要多。

这是来自活动监视器的图片(索引后流量较低):

这是在 Azure ExtraLarge VM(8 核 14GB 内存)上运行的 - vm 什么都不做,只是运行一个带有 1 个表的 sql server,它只翻译这个 1 个请求!在这种较低流量上的 VM CPU 约为 30%,在较高流量上约为 70%,我相信一些结构/逻辑更改应该可以让一个非常小的服务器\服务轻松处理这个问题。

【问题讨论】:

    标签: sql sql-server performance indexing virtual-machine


    【解决方案1】:
    SELECT TOP 1 *
    FROM IP
    WHERE StartIP <= yourIP
    ORDER BY StartIP
    

    这将为您提供高于给定 IP 的最近 IP 范围。然后您需要测试 EndIP 是否也匹配。所以:

    SELECT *
    FROM (
     SELECT TOP 1 *
     FROM IP
     WHERE StartIP <= yourIP
     ORDER BY StartIP
    ) x
    WHERE EndIP >= yourIP
    

    这相当于单行索引查找。完美的表现。

    SQL Server 不能自动执行此操作的原因是它无法知道 IP 范围是有序的,这意味着下一个StartIP 总是大于当前的EndIP。我们可以有(100, 200), (150, 250) 形式的范围。这显然是无效的,但它可能在表格中。

    【讨论】:

    • 应该是 SELECT * FROM (SELECT TOP 1 * FROM IP WHERE StartIP = yourIP
    • 可能,不确定。你测试了吗?
    • 测试了查询返回相同的结果,现在测试性能,我会在这里评论:)
    【解决方案2】:

    在我的意见中,您的主要问题是缺乏“参数化”,因为 (a) 查询编译是/可能很昂贵,并且 (b) 这些“未参数化”的查询似乎有很多执行.可用的屏幕截图显示了关于这方面的两件事:

    1) 最近昂贵的查询没有“参数化”。

    2) “计划计数”的高值:

    Plan Count 此查询的缓存查询计划数。一个大的 number 可能表明需要显式查询参数化。为了 更多信息,请参阅指定查询参数化行为 使用计划指南。

    Source

    所以,我会尝试为这些查询使用参数:

    SELECT TOP(1) CountryId FROM [IP] WHERE Column1 <= @param AND @param <= Column2
    

    如果您无法更改应用程序(如何将 SQL 请求发送到 SQL Server),那么您可以尝试计划指南: http://technet.microsoft.com/en-US/library/ms191275(v=sql.90).aspx

    【讨论】:

    • 这将执行一个昂贵的索引交集。索引查找将平均产生表的一半。这是他的主要问题。
    • 一半?你很清楚。如果你真的很仔细,我并不是说这是唯一的问题。但应该是第一步,也是最简单的一步。
    • 平均一半,是的。将读取大于给定 IP 的所有内容。 IP 是随机分布的。
    猜你喜欢
    • 2018-03-27
    • 2018-05-24
    • 1970-01-01
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 2022-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多