SQL:优化问题,有行吗?

发布于 2024-07-26 08:17:40 字数 313 浏览 0 评论 0原文

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

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

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

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

有任何想法吗?

I got a query with five joins on some rather large tables (largest table is 10 mil. records), and I want to know if rows exists. So far I've done this to check if rows exists:

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

Using this query, in a stored procedure takes 22 seconds and I would like it to be close to "instant". Is this even possible? What can I do to speed it up?

I got indexes on the fields that I'm joining on and the fields in the WHERE clause.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

岁月打碎记忆 2024-08-02 08:17:41

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

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

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

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

Depending on your RDBMS you can check what parts of the query are taking a long time and which indexes are being used (so you can know they're being used properly).

In MSSQL, you can use see a diagram of the execution path of any query you submit.

In Oracle and MySQL you can use the EXPLAIN keyword to get details about how the query is working.

But it might just be that 22 seconds is the best you can do with your query. We can't answer that, only the execution details provided by your RDBMS can. If you tell us which RDBMS you're using we can tell you how to find the information you need to see what the bottleneck is.

埋情葬爱 2024-08-02 08:17:41

4 个选项

  • 尝试用 COUNT(*) 代替 TOP 1 tbl.id

  • 每列的索引可能不够好:您可能会需要使用复合索引

您使用的是 SQL Server 2005 吗? 如果有,您可以找到丢失的索引。 或者尝试数据库调整顾问

  • 另外,您可能不'不需要 5 个连接。

假设父子孙等,那么没有父行就不能存在孙子行(假设您有外键),

因此您的查询可能会变成

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

对于 5 个表或假设的层次结构

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*/)

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*/)
妄想挽回 2024-08-02 08:17:41

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

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

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

Doing a filter early on your first select will help if you can do it; as you filter the data in the first instance all the joins will join on reduced data.

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

After that you will likely need to provide more of the query to understand how it works.

流年里的时光 2024-08-02 08:17:41

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

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

Maybe you could offload/cache this fact-finding mission. Like if it doesn't need to be done dynamically or at runtime, just cache the result into a much smaller table and then query that. Also, make sure all the tables you're querying to have the appropriate clustered index. Granted you may be using these tables for other types of queries, but for the absolute fastest way to go, you can tune all your clustered indexes for this one query.

Edit: Yes, what other people said. Measure, measure, measure! Your query plan estimate can show you what your bottleneck is.

囚我心虐我身 2024-08-02 08:17:41

在每个连接中首先使用最大行表,如果有多个条件使用
in where then where 条件的顺序很重要 使用条件
这给你最大的行数。

非常小心地使用过滤器来优化查询。

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.

默嘫て 2024-08-02 08:17:40

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

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

switch to EXISTS predicate. In general I have found it to be faster than selecting top 1 etc.

So you could write like this IF EXISTS (SELECT * FROM table tbl INNER JOIN table tbl2 .. do your stuff

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文