我在一些相当大的表上得到了一个带有五个连接的查询(最大的表是10密耳。记录),我想知道行是否存在。到目前为止,我已经这样做以检查行是否存在:
SELECT TOP 1 tbl.Id
FROM table tbl
INNER JOIN ... ON ... = ... (x5)
WHERE tbl.xxx = ...
使用此查询,在存储过程中需要22秒,我希望它接近“即时”。这甚至可能吗?我该怎么做才能加快速度?
我在我加入的字段和WHERE子句中的字段上有索引。
有什么想法吗?
答案 0 :(得分:3)
切换到EXISTS谓词。一般来说,我发现它比选择前1等更快。
所以你可以这样写IF EXISTS (SELECT * FROM table tbl INNER JOIN table tbl2 .. do your stuff
答案 1 :(得分:3)
根据您的RDBMS,您可以检查查询的哪些部分需要很长时间以及正在使用哪些索引(这样您就可以知道它们已被正确使用)。
在MSSQL中,您可以使用查看您提交的任何查询的执行路径图。
在Oracle和MySQL中,您可以使用EXPLAIN关键字获取有关查询如何工作的详细信息。
但它可能只是22秒是你可以用你的查询做的最好的。我们无法回答这个问题,只有RDBMS提供的执行细节才能解决。如果你告诉我们你正在使用哪种RDBMS,我们可以告诉你如何找到你需要的信息,看看瓶颈是什么。
答案 2 :(得分:2)
4个选项
尝试COUNT(*)代替TOP 1 tbl.id
每列的索引可能不够好:您可能需要使用复合索引
您使用的是SQL Server 2005吗?如果是som,你可以找到丢失的索引。或者尝试database tuning advisor
假设父子孙等,那么没有父行的孙子行就不存在(假设你有外键)
所以你的查询可能会变成
SELECT TOP 1
tbl.Id --or count(*)
FROM
grandchildtable tbl
INNER JOIN
anothertable ON ... = ...
WHERE
tbl.xxx = ...
对于5个表或假设的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*/)
答案 3 :(得分:1)
如果可以的话,在第一次选择时尽早做一个过滤器会有所帮助;当您在第一个实例中过滤数据时,所有连接都将加入减少的数据。
Select top 1 tbl.id
From
(
Select top 1 * from
table tbl1
Where Key = Key
) tbl1
inner join ...
之后,您可能需要提供更多查询以了解其工作原理。
答案 4 :(得分:0)
也许你可以卸载/缓存这个事实调查任务。就像它不需要动态地或在运行时完成一样,只需将结果缓存到一个小得多的表中然后查询它。此外,请确保您查询的所有表都具有相应的聚簇索引。您可以将这些表用于其他类型的查询,但是对于绝对最快的方法,您可以为这一个查询调整所有聚簇索引。
编辑:是的,其他人说的话。测量,测量,测量!您的查询计划估算可以显示您的瓶颈是什么。
答案 5 :(得分:0)
如果使用多个条件,则在每个连接中首先使用maximun行表 在那里,那里的条件的顺序是重要的使用条件 它给你最大的行。
非常谨慎地使用过滤器来优化查询。