繁体   English   中英

编写命名SQL查询并返回是否存在行的最佳方法?

[英]Best way to write a named SQL query that returns if row exists?

所以我有这个SQL查询,

<named-query name="NQ::job_exists">
<query>
select 0 from dual where exists (select * from job_queue);
</query>
</named-query>

我打算这样使用:

Query q = em.createNamedQuery("NQ::job_exists");
        List<Integer> results = q.getResultList();
        boolean exists = !results.isEmpty();
        return exists;

但是我在SQL / JPA方面不是很坚强,并且想知道是否有更好的方法(或改进方法)。 例如,我应该写(从job_queue jq中选择jq.id)而不是星号吗?

编辑:此调用在我们的应用程序中对性能至关重要。

编辑:进行了一些性能测试,尽管差异几乎可以忽略不计,但我最终决定采用:

select distinct null
    from dual 
       where exists (
               select null from job_queue
       );

如果您使用的是EXISTS Oracle,建议使用null

select null 
  from dual where exists (select null from job_queue);

以下是在Oracle上成本较低的解决方案:

select null
  from job_queue
 where rownum = 1;

更新:要包括表上没有行的情况,可以运行以下查询:

select count(*)
  from (select null
          from job_queue
          where rownum = 1);

通过此查询,您将获得最佳计划,并且只有两个可能的结果:如果有行,则为1如果没有行,则为0

如果您执行“存在”,则一旦找到匹配项,它将立即停止查找。 这样可以阻止它进行全表扫描。 如果您没有ORDER BY,则与TOP 1相同。 如果您执行的是TOP 1 ID,并且ID在索引中,则它可能会使用该索引,甚至根本不会访问该表。 停止全表扫描是最大程度地节省性能的地方。

另一个小节省是,如果您执行“ SELECT 1”或“ SELECT COUNT(1)”而不是“ SELECT *”或“ SELECT COUNT(*)”,则可以节省获取表结构的工作。

所以我会去:

SELECT TOP 1 1 AS Found
FROM job_queue

然后:
返回!results.isEmpty();

这是我能想到的最少的工作。

对于Oracle,它将是:

SELECT 1 
FROM job_queue
WHERE rownum<2;

要么:

Set Rowcount 1
SELECT 1 
FROM job_queue

为什么不做:

select count(*) as JobCount from job_queue

如果JobCount = 0,那就有您的答案!

暂无
暂无

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

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