2

在使用具有多个范围的映射表时,我遇到了性能问题。映射表的布局如下。

ResultNumber param1Min param1Max param2Min param2Max ... param8min param8max

这些是映射表的列名。桌子上连接的是param1, param2, param3 ... param8.

我需要找到(param1 在 param1Min 和 param1Max 之间)和(param2 在 param2Min 和 param2Max 之间)的行......并从匹配的行中获取结果编号。问题是映射表有超过 200 万行,我无法索引该表,因为它必须使用范围来查找所需的内容。

关于如何加快速度的任何想法?

我还包括了我尝试过的完全没有帮助的索引

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)
4

1 回答 1

0

“param1,param2,param3 ... param8”变量或列在另一个表中吗?在任何情况下,我都会将它分成块以从索引中获取使用情况,并减少每次后续参数检查需要完成的工作。

您想在 resultnumber 和仅 resultnumber 上创建聚集索引,然后在 resultnumber、param#min、param#max 组合上创建非聚集索引。应该是 [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)

这将允许您从下面的代码中获得性能提升。它应该运行得非常快。

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

表实现看起来像这样。根据您要加入的表的大小,它仍需要一段时间,但它的运行速度仍应比原始查询快。

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
于 2012-12-20T02:44:57.693 回答