简体   繁体   English

如何使用子查询优化 SQL 查询?

[英]How to optimize the SQL query with the subquery?

I want to improve the performance of a SQL query.我想提高 SQL 查询的性能。 I have the table 'tblEntries' with the column 'sTag':我有表 'tblEntries' 和列'sTag':

+----+------+-------+------+---------+
| Id | sTag | sPath | lVer | bActive |
+====+======+=======+======+=========+
| 1  | NULL |  t1   | 100  |   +     |
| 2  | NULL |  t2   | 110  |   +     |
| 3  | x1   |  t4   | 110  |   +     |
| 4  | x1   |  t3   | 120  |   +     |
| 5  | x2   |  t7   | 100  |   +     |
+----+------+-------+------+---------+

A client queries for the path with the specified tag and the query should return a specified entry with the next condition:客户端查询具有指定标记的路径,查询应返回具有下一个条件的指定条目:

  1. If there is an entry with the specified tag it should returns the entry with the maximum lVer value and bActive should be TRUE.如果有一个带有指定标签的条目,它应该返回具有最大 lVer 值的条目,并且 bActive 应该是 TRUE。
  2. If there is no entry with the specified tag it should returns the entry with the NULL sTag value and with the maximum lVer value and bActive should be TRUE.如果没有带有指定标签的条目,它应该返回带有 NULL sTag 值和最大 lVer 值的条目,并且 bActive 应该为 TRUE。

The "tagged" entry has the more priority over "non-tagged" one. “标记”条目比“未标记”条目具有更高的优先级。

The current SQL query is:当前 SQL 查询为:

SELECT lVer, sPath 
FROM tblEntries 
INNER JOIN 
(SELECT MAX(lVer) AS V, sTag AS T 
FROM tblEntries 
WHERE bActive = TRUE 
GROUP BY sTag)
ON lVer = V 
WHERE T IS NULL OR T = 'user_tag' 
ORDER BY T DESC

Then i can select the first entry which satisfies the conditions.然后我可以 select 第一个满足条件的条目。 Can i avoid the subquery?我可以避免子查询吗?

Thanks!谢谢!

Depending on your data and database, this might have sufficient performance:根据您的数据和数据库,这可能具有足够的性能:

select top (1) e.*
from tblEntries e
where e.bActive = TRUE and
      (e.t IS NULL OR e.t = 'user_tag')
order by (e.t desc),  -- null values last
         t.lver desc;

If speed is really an issue and you have an index on (t, active, lver desc) , this might be a bit faster:如果速度确实是个问题,并且您在(t, active, lver desc)上有一个索引,那么这可能会快一点:

(select top (1) e.*
 from tblEntries e
 where e.t = 'user_tag' and e.bActive = TRUE 
 order by e.lver desc
) union all
(select top (1) e.*
 from tblEntries e
 where e.t is null and e.bActive = TRUE and
       not exists (select 1 from tblEntries e2 where e2.t = 'user_tag' and e2.bActive = TRUE )
 order by e.lver desc
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM