编写命名SQL查询的最佳方法,如果存在行则返回该查询?

时间:2010-02-13 04:17:55

标签: sql oracle hibernate

所以我有这个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
       );

3 个答案:

答案 0 :(得分:5)

如果您使用的是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

答案 1 :(得分:3)

如果您执行“存在”,则会在找到匹配后立即停止查看。这可以阻止它进行全表扫描。如果您没有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

然后:
       return!results.isEmpty();

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

对于Oracle,它将是:

SELECT 1 
FROM job_queue
WHERE rownum<2;

或者:

Set Rowcount 1
SELECT 1 
FROM job_queue

答案 2 :(得分:1)

为什么不这样做:

select count(*) as JobCount from job_queue

如果JobCount = 0,那么就是你的答案!