Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 加速使用WHERE-IN进行筛选的动态SQL查询_Performance_Tsql_Join - Fatal编程技术网

Performance 加速使用WHERE-IN进行筛选的动态SQL查询

Performance 加速使用WHERE-IN进行筛选的动态SQL查询,performance,tsql,join,Performance,Tsql,Join,考虑以下数据表: CREATE TABLE Person ( PersonId int PRIMARY KEY ) CREATE TABLE PersonData ( PersonId int, -- with foreign key to person table DateKey Date, Fact1 int, ) 我可以执行这样的查询,它将聚合Fact1,并按DateKey分组 SELECT DateKey, SUM(Fact1) FROM Pers

考虑以下数据表:

CREATE TABLE Person
(
    PersonId int PRIMARY KEY
)

CREATE TABLE PersonData 
(
    PersonId int, -- with foreign key to person table
    DateKey Date,
    Fact1 int,
)
我可以执行这样的查询,它将聚合Fact1,并按DateKey分组

SELECT DateKey, SUM(Fact1) 
FROM PersonData
GROUP BY DateKey
现在让我们假设我想按personId过滤并显示id为1、2和3的人员的数据。我可以这样做:

SELECT DateKey, SUM(Fact1) 
FROM PersonData
WHERE PersonId IN (1, 2, 3)
GROUP BY DateKey
这是一个问题,如果我有大量的人形,我想过滤。i、 e.其中T2.PersonId在(1,2,3,4,5…1000+)

如果要筛选大量PersonId,如何提高性能

更新

虽然上面的例子是对我的数据结构的简化,但希望它是一个准确的类比

示例查询和时间影响,考虑到大约3200万行PersonData和2000个独特人物:

  • 对单个PersonId进行过滤:100ms
  • 完全没有过滤器:750毫秒
  • 在1500个人身上过滤:2300 ms
注意:对于所有查询,我还将执行WHERE子句以将DateKey(日期维度表的外键)限制为1个月的时间跨度。

尝试以下操作:

declare @beginValue int = 1,
        @endValue int = 87;

--Only work if you need a interval of numbers (example: 1 to 87, in Person table)
SELECT pdt.DateKey, SUM(pdt.Fact1)
FROM PersonData AS pdt
     INNER JOIN Person AS per ON pdt.PersonId = per.PersonId
WHERE per.PersonId BETWEEN @beginValue AND @endValue
GROUP BY pdt.DateKey;

您可以尝试将所有PersonId加载到SQL中的表中。然后使用:

SELECT DateKey, SUM(Fact1) 
FROM PersonData D
WHERE exists (SELECT 1 from PersonIDTable I where d.PersonID = I.PersonID)
GROUP BY DateKey

这通常会使查询运行得更快

是否大部分时间都花在了“groupby”子句中

请看一下执行计划


我想知道增加个人ID列表是否真的会导致DateKey排序成本线性增加。如果是这样,请在DateKey列上添加一个索引。

我假设您不能将
T2.PersonId
-空间表示为某种查询?这意味着它必须是一个
id
列表?假设
Person->PersonData
是一对多,那么您所说的提高性能的
Person
上的连接看起来是多余的。计划是什么样子的?您的表上有哪些索引?@jonnyGold-它不一定是一个ID列表,但是需要对应用程序进行大量重构才能将过滤器表示为连接,而不是一组ID。“我在这里寻找一个快速解决办法。”马丁史密斯说得对,这是一对多。不知道为什么它会提高性能。这个例子是我认为问题所在的一个粗略简化。希望它是有代表性的…@MartinSmith经过额外的测试,你是正确的。加入似乎没有什么不同。我已经从我的帖子中删除了这些信息。这很快,但没有用。通常情况下,这些值不会是顺序的,因为这会导致改进(1700ms),但不是一个很大的改进,并且我会失去插入的改进(然后是一些)。ID列表是动态的/由用户根据他们设置的过滤器选择的-因此我不能提前填充这样的表。