zoukankan      html  css  js  c++  java
  • 浅析尽量不用count(*)来判断是否有数据、判断记录是否存在 exists 和 top 1 要比 count 快

    一、问题描述

      首先说一下,判断表里是否有记录,常见的写法(伪代码)

    -- 定义变量a 
    a = (select count(*) from tb)
    if a > 0 ...
    else ...

      这么写是没错,看上去也好理解,就是统计一下tb表中的记录数,然后判断这个记录数是否大于0。可能绝大多数人在实现这个需求的时候,都会这么写。

      接下来,想想这个语句在执行时,会做什么处理:

    1、如果tb表没索引,那么会有表扫描,如果表中的记录数很大,这个操作会很慢。

    2、如果tb表有索引,那么会有索引扫描操作,计算索引记录有多少条。同样的,如果记录数很大,这个操作不会太快,但肯定比第1种情况要快的多。

      那么,有没有更好的办法,来实现这个需求呢?

    二、优化方案

      这里先想想这个需求本身,就是要判断tb表中是否有记录。上面这句话的意思很明确,仔细想想,判断结果是:要么有,要么没有,而至于表中到底有多少条记录,这种精确的信息,他是不关注的。所以,我们可以朝着这个方向去优化,我想到的办法有2个:

    1、exists

    a = case when exists(select id from tb) then 1 else 0 end

    2、返回1条记录

    -- 方式1
    a = (select count(1) from tb where rownum=1) 
    
    -- 方式2
    a = (select count(1) from (select top 1 id from tb ) t) 

    3、两种方法的对比

      上面的2种改进的写法,虽然具体的实现方式不一样,一个是用 exists,一个是用 top 或 rownum 来限制返回1条记录,但意思是相同的,就是只看表里是否有记录,不关注记录数。

      就这么一个简单的需求,实现起来虽然很简单,但是,如果不好好想想,深入理解需求的本质,恐怕也不容易有个好的实现(这里的“实现”两字,表示把需求转化为代码的过程),更何况其他更加复杂的需求。

    三、判断记录是否存在: exists 和 top 1 要比 count 快

      之前在程序中验证记录是否存在,总是用 select count(0) from table1 得到记录数,然后在比对,思考有没有性能更好的办法。

      思考 count 的工作原理后感觉是读取所有数据后进行统计的,而使用 top 1 会不会只是取得第一个纪录后就跳出查询呢?

      正好手头上有朋友上次做实验制作的一个300万记录的表,我就用来做了下实验

    select count(0) from table1
    -- 执行时间 两次分别是 3秒,1秒
    
    select top 1 0 from table1
    -- 两次执行时间都为0秒
    
    exists( select  0 from table1)
    -- 两次都为0秒
  • 相关阅读:
    POJ 2018 二分
    873. Length of Longest Fibonacci Subsequence
    847. Shortest Path Visiting All Nodes
    838. Push Dominoes
    813. Largest Sum of Averages
    801. Minimum Swaps To Make Sequences Increasing
    790. Domino and Tromino Tiling
    764. Largest Plus Sign
    Weekly Contest 128
    746. Min Cost Climbing Stairs
  • 原文地址:https://www.cnblogs.com/goloving/p/15230869.html
Copyright © 2011-2022 走看看