简体   繁体   English

SQL Server-用最小和最大范围索引映射表

[英]SQL Server - Index a Mapping table with min and max range

I am having an issue with performance when it comes to using a mapping table that has multiple ranges. 在使用具有多个范围的映射表时,性能存在问题。 The mapping table is laid out like the following. 映射表的布局如下所示。

ResultNumber param1Min param1Max param2Min param2Max ... param8min param8max

Those are the column names of the mapping table. 这些是映射表的列名。 What is joined on the table is param1, param2, param3 ... param8 . 在表上连接的是param1, param2, param3 ... param8

I need to find the row where (param1 is between param1Min and param1Max) and (param2 is between param2Min and param2Max) ... and get the Result number from the matching row. 我需要找到其中(param1在param1Min和param1Max之间)和(param2在param2Min和param2Max之间)...的行,并从匹配的行中获取结果编号。 The issue is the mapping table has over 2 million rows and I am having trouble indexing this table because it has to use ranges to find what it needs. 问题是映射表有超过200万行,我在索引该表时遇到了麻烦,因为它必须使用范围来查找所需的内容。

Any thoughts on how to speed this up? 对如何加快速度有任何想法吗?

I also included the index I tried that did not help at all 我还包括了我尝试过的索引,但该索引根本没有帮助

SELECT ResultNumber
FROM   MappingTable
WHERE  ( param1 BETWEEN param1Min AND param1Max )
       AND ( param2 BETWEEN param2Min AND param2Max )
       AND ( param3 BETWEEN param3Min AND param3Max ) 
 ...



CREATE CLUSTERED INDEX [index] ON [dbo].MappingTable 
(
    [param1Min] ASC,
    [param1Max] ASC,
    [param2Min] ASC,
    [param2Max] ASC,
    [param3Min] ASC,
    [param3Max] ASC,
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON)

Are the "param1, param2, param3 ... param8" variables or columns in another table? 是“ param1,param2,param3 ... param8”变量还是其他表中的列? In any event I would break it into chunks to get usage out of the indexes and slice down the work that needs to be done with each subsequent parameter check. 无论如何,我都会将其分解成多个块,以使索引无法使用,并缩减每次后续参数检查所需完成的工作。

You want to create a clustered index on resultnumber and only resultnumber and then create nonclustered indexes on resultnumber, param#min, param#max combinations. 您要在resultnumber和only resultnumber上创建聚簇索引,然后在resultnumber,param#min和param#max组合上创建非聚簇索引。 Should be a total of 9 indexes on [dbo].[MappingTable]. 在[dbo]。[MappingTable]上应该总共有9个索引。

Create Clustered Index ix_rn On [dbo].[MappingTable] (resultnumber)
Create NonClustered Index ix_p1 On [dbo].[MappingTable] (resultnumber, param1min, param1max)
...
Create NonClustered Index ix_p8 On [dbo].[MappingTable] (resultnumber, param8min, param8max)

This will allow you to get performance gains from the code below. 这将使您从下面的代码获得性能提升。 It should run extremely fast. 它应该运行得非常快。

With    param1 As
(
        Select  resultnumber
        From    [dbo].[MappingTable]
        Where   @param1 Between param1min And param1max
),      param2 As
(
        Select  m.resultNumber
        From    [dbo].[MappingTable] m
        Join    param1 p1
                On  m.resultnumber = p1.resultnumber
        Where   @param2 Between param2min And param2max
),      param3 As
(
        ...
        ...
),      param8 As
(
        Select  m.resultNumber
        From    [dbo].[MappingTable] m
        Join    param7 p7
                On  m.resultnumber = p7.resultnumber
        Where   @param8 Between param8min And param8max
)
Select  resultNumber
From    param8

A table implementation would look something like this. 表实现看起来像这样。 It would still take awhile depending on the size of the table you're joining, but it should still run faster than your original query. 仍然需要一段时间,具体取决于要连接的表的大小,但它的运行速度仍应比原始查询快。

With    param1 As
(
        Select  m.resultnumber, w.tableIdentityValue
        From    [dbo].[MappingTable] m
        Join    whateverJoinTable w
                On w.param1 Between m.param1min And m.param1max
),      param2 As
(
        Select  m.resultNumber, w.tableIdentityValue
        From    [dbo].[MappingTable] m
        Join    param1 p1
                On  m.resultnumber = p1.resultnumber
        Join    whateverJoinTable w
                On  m.tableIdentityValue = w.tableIdentityValue
                And w.param2 Between m.param2min And m.param2max
),      param3 As
(
        ...
        ...
),      param8 As
(
        Select  m.resultNumber, w.tableIdentityValue
        From    [dbo].[MappingTable] m
        Join    param7 p7
                On  m.resultnumber = p7.resultnumber
        Join    whateverJoinTable w
                On  m.tableIdentityValue = w.tableIdentityValue
                And w.param8 Between m.param8min And m.param8max
)
Select  resultNumber, tableIdentityValue
From    param8

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM