Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.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
如何在T-SQL中使用多表排序优化联接?_Sql_Sql Server_Sql Server 2005_Tsql_Query Optimization - Fatal编程技术网

如何在T-SQL中使用多表排序优化联接?

如何在T-SQL中使用多表排序优化联接?,sql,sql-server,sql-server-2005,tsql,query-optimization,Sql,Sql Server,Sql Server 2005,Tsql,Query Optimization,如何优化以下查询 SELECT TOP 50 * FROM A LEFT JOIN B ON A.b_id = B.id ORDER BY A.number, B.name DESC 我在(a.number asc,a.creation_date desc)上创建了一个非聚集索引,其中包括a中的所有列,在B.origination_date desc上创建了另一个非聚集索引,其中包括B中的所有列(文本列除外)。根据SQLServerManagementStudio的实际执

如何优化以下查询

   SELECT TOP 50 *
     FROM A 
LEFT JOIN B ON A.b_id = B.id 
 ORDER BY A.number, B.name DESC
我在(a.number asc,a.creation_date desc)上创建了一个非聚集索引,其中包括a中的所有列,在B.origination_date desc上创建了另一个非聚集索引,其中包括B中的所有列(文本列除外)。根据SQLServerManagementStudio的实际执行计划,这两个索引都没有使用

造成性能下降的原因似乎是B.origination\U日期排序。当我在SQLServerManagementStudio中检查实际执行计划时,我看到这三个字段上的“TopN排序”占用了91%的执行时间。如果我在B.origination_日期放弃排序,查询几乎会立即完成,使用A上的索引

编辑:
更新了查询以提供更好、更简单的示例。

我想,像“%”这样的数字是您的问题。这样做的目的是什么?如果要使用索引,则不应使用带有通配符的like作为第一个字符。这样看来,它似乎没有过滤任何内容,因为通配符之间没有tere

如果没有亲身体验,就很难想出硬性和快速的解决方案。一些想法和建议:

如果没有表B上的联接,SQL所要做的(索引在A.Number上)就是遍历,直到找到与您的模式匹配的前50行。如果“Number”的值是相对唯一的(没有太多重复项[这是基数]),那么在索引中包含Creation_Date也没有什么价值

为什么左边的外部连接到B?是一对[零或一],还是一对[零或多]?如果基数很低(A中有许多重复项),那么连接需要清楚地找到“前50个”,否则人们会认为连接不会影响性能(除了执行连接的需要)。我看不到B上的任何索引(除了列id)在这里有任何区别。嗯,你有B.Id的索引,对吗?如果不是,这可能会大大降低速度(当然,假设B有大量行)

对于更多的sepcifics,我想回顾join和orderby列的基数,并仔细查看“with join”查询的执行计划


附录

如果A的基数较低(有许多重复项),那么查询优化器可能会“认为”必须使用lot B.Id来解析排序(必须这样做才能找到前50个)。这或许可以解释为什么它会这么做


如果它们将产生100%的等效结果,我建议将左连接替换为内部连接。一般来说,当具有更严格的联接条件时,查询计划会变得更简单。

因为您要对来自两个不同表的列进行排序,SQL Server必须联接这些表,然后进行排序。一旦连接了表,各个表上的索引对排序没有任何帮助。索引视图可能是最佳选择。

目的是返回所有记录。正如我提到的,大部分执行时间都花在排序上。删除where子句不会产生影响;我将编辑上面的问题并删除它。好问题,谢谢。关系是多对一(多个A对一个B),内部联接也可以正常工作。我更新了示例以删除日期字段,您是对的,它不是很有用。我真正想要的是按A.数字,B.名称排序;上面修改过的查询显示了相同的问题。该查询使用B的聚集主键,并对A的新索引进行索引扫描。我不明白的是,为什么在加入A和B之后,查询要花这么多时间进行另一种排序;似乎因为A的索引已经排序,它(直观地)应该需要做的工作更少;因此使用B来区分它们,作为第二类。