3

我在一些相当大的表上得到了一个包含五个连接的查询(最大的表是 1000 万条记录),我想知道行是否存在。到目前为止,我已经这样做来检查行是否存在:

SELECT TOP 1 tbl.Id
FROM table tbl
INNER JOIN ... ON ... = ... (x5)
WHERE tbl.xxx = ...

使用此查询,在存储过程中需要 22 秒,我希望它接近“即时”。这甚至可能吗?我该怎么做才能加快速度?

我获得了要加入的字段和 WHERE 子句中的字段的索引。

有任何想法吗?

4

6 回答 6

3

切换到 EXISTS 谓词。一般来说,我发现它比选择前 1 等更快。

所以你可以这样写IF EXISTS (SELECT * FROM table tbl INNER JOIN table tbl2 .. do your stuff

于 2009-07-08T12:56:49.103 回答
3

根据您的 RDBMS,您可以检查查询的哪些部分花费了很长时间以及正在使用哪些索引(这样您就可以知道它们正在被正确使用)。

在 MSSQL 中,您可以使用查看您提交的任何查询的执行路径图。

在 Oracle 和 MySQL 中,您可以使用 EXPLAIN 关键字来获取有关查询如何工作的详细信息。

但它可能只是 22 秒是您对查询所能做的最好的事情。我们无法回答这个问题,只有您的 RDBMS 提供的执行细节可以。如果您告诉我们您正在使用哪个 RDBMS,我们可以告诉您如何找到所需的信息以了解瓶颈所在。

于 2009-07-08T12:57:28.150 回答
2

4 options

  • Try COUNT(*) in place of TOP 1 tbl.id

  • An index per column may not be good enough: you may need to use composite indexes

Are you on SQL Server 2005? If som, you can find missing indexes. Or try the database tuning advisor

  • Also, it's possible that you don't need 5 joins.

Assuming parent-child-grandchild etc, then grandchild rows can't exist without the parent rows (assuming you have foreign keys)

So your query could become

SELECT TOP 1
   tbl.Id --or count(*)
FROM
   grandchildtable tbl
   INNER JOIN
   anothertable ON ... = ...
WHERE
   tbl.xxx = ...
  • Try EXISTS.

For either for 5 tables or for assumed heirarchy

SELECT TOP 1 --or count(*)
   tbl.Id
FROM
   grandchildtable tbl
WHERE
   tbl.xxx = ...
   AND
   EXISTS (SELECT *
       FROM
           anothertable T2
       WHERE
           tbl.key = T2.key /* AND T2 condition*/)
-- or
SELECT TOP 1 --or count(*)
   tbl.Id
FROM
   mytable tbl
WHERE
   tbl.xxx = ...
   AND
   EXISTS (SELECT *
       FROM
           anothertable T2
       WHERE
           tbl.key = T2.key /* AND T2 condition*/)
   AND
   EXISTS (SELECT *
       FROM
           yetanothertable T3
       WHERE
           tbl.key = T3.key /* AND T3 condition*/)
于 2009-07-08T13:10:01.437 回答
1

如果可以的话,在第一次选择时尽早进行过滤会有所帮助;当您在第一个实例中过滤数据时,所有连接都将连接到减少的数据。

Select top 1 tbl.id
From 
(
Select top 1 * from 
table tbl1
Where Key = Key
) tbl1
inner join ... 

之后,您可能需要提供更多查询以了解其工作原理。

于 2009-07-08T12:56:06.717 回答
0

Use the maximun row table first in every join and if more than one condition use in where then sequence of the where is condition is important use the condition which give you maximum rows.

use filters very carefully for optimizing Query.

于 2009-07-08T13:10:21.047 回答
0

也许你可以卸载/缓存这个事实调查任务。就像它不需要动态或在运行时完成一样,只需将结果缓存到一个小得多的表中,然后查询它。此外,请确保您要查询的所有表都具有适当的聚集索引。当然,您可能会将这些表用于其他类型的查询,但要获得绝对最快的方法,您可以针对这一查询调整所有聚集索引。

编辑:是的,其他人说的。测量,测量,测量!您的查询计划估计可以显示您的瓶颈是什么。

于 2009-07-08T12:57:37.963 回答