mysql中对一个表的id建立了唯一索引,那么查询的select count(*) ,select count(1) ,select count(id),select count(列名)

1.mysql中对一个表的id建立了唯一索引,那么查询的select count(*) ,select count(1) ,select count(id),select count(列名) 的查询结果又什么不同,及索引的使用情况

先说结论:

①对id 建立索引,select count(*) ,select count(1) 和select count(id) 这三者等效,会统计为null的数据

   都会走index 级别的索引,并且不会回表,

   因为只做统计数据,没有用到其他字段(Extra的  Using index 就说明了 这种情况)

② select count(某个列名),只统计该列名不为null的情况,如果没有对该列名,建立索引,那么就会全表

 

用途:在数据量特别大的时候测试,两个表之间有没有关系,就用count(主键) 基本上不用的等待就可以 查到想要的结果(尤其是在表数据量特别大的时候特别有用)

比如:

#  最新认知(重要) :inner join 取交集不是 数目取交集,eg: boys 只有一个 id 为 1 的数据,但是 girl有 8 条 boy_id 为 1 的记录,
#  最后的的结果 数量就是 8,大于 boys 表的一条数据(唯一确定的是小于等于 笛卡尔集 (男生表count*女生表count))
# 8 有女朋友的男生信息
select count(boys.id) from boys inner join girl on  boys.id = girl.boy_id ;

以下是测试sql和脚本:

create table sql_test.boys
(
    id      int                     not null,
    name    varchar(20)             null,
    sex     varchar(20) default '男' null comment '默认男',
    age     varchar(20)             null,
    address int                     null,
    constraint boys_id_uindex
        unique (id)
)
    comment '男生表';

 select * from boys ;
# +--+----+---+---+-------+
# |id|name|sex|age|address|
# +--+----+---+---+-------+
# |1 |慕容皝 |男  |22 |NULL   |
# |2 |慕容冲 |男  |33 |NULL   |
# |3 |慕容垂 |男  |44 |NULL   |
# |4 |慕容博 |男  |55 |NULL   |
# |5 |慕容雪 |女  |55 |NULL   |
# |6 |慕容复 |男  |55 |NULL   |
# |7 |慕容龙城|女  |55 |NULL   |
# +--+----+---+---+-------+

# 因为我对id 建立了唯一索引
# 7 type : index ;key :boys_id_uindex ;Extra :Using index(ps:不需要表,只做统计)
select count(*) from boys;
# +--+-----------+-----+----------+-----+-------------+--------------+-------+----+----+--------+-----------+
# |id|select_type|table|partitions|type |possible_keys|key           |key_len|ref |rows|filtered|Extra      |
# +--+-----------+-----+----------+-----+-------------+--------------+-------+----+----+--------+-----------+
# |1 |SIMPLE     |boys |NULL      |index|NULL         |boys_id_uindex|4      |NULL|8   |100     |Using index|
# +--+-----------+-----+----------+-----+-------------+--------------+-------+----+----+--------+-----------+
# 7
select count(1) from boys;
# +--+-----------+-----+----------+-----+-------------+--------------+-------+----+----+--------+-----------+
# |id|select_type|table|partitions|type |possible_keys|key           |key_len|ref |rows|filtered|Extra      |
# +--+-----------+-----+----------+-----+-------------+--------------+-------+----+----+--------+-----------+
# |1 |SIMPLE     |boys |NULL      |index|NULL         |boys_id_uindex|4      |NULL|8   |100     |Using index|
# +--+-----------+-----+----------+-----+-------------+--------------+-------+----+----+--------+-----------+
# 说明: select count(*) from boys 和  select count(1) from boys; 两条sql 都走了索引,
# 并且没有回表,说明 和下面的sql等效(说明:boys 上 对 id 建立了 唯一索引)
# 7
select count(id) from boys;
# +--+-----------+-----+----------+-----+-------------+--------------+-------+----+----+--------+-----------+
# |id|select_type|table|partitions|type |possible_keys|key           |key_len|ref |rows|filtered|Extra      |
# +--+-----------+-----+----------+-----+-------------+--------------+-------+----+----+--------+-----------+
# |1 |SIMPLE     |boys |NULL      |index|NULL         |boys_id_uindex|4      |NULL|8   |100     |Using index|
# +--+-----------+-----+----------+-----+-------------+--------------+-------+----+----+--------+-----------+


# 0 type:all   ; 因为 address 没加索引,走的是 全表扫描
select count(address) from boys;
# +--+-----------+-----+----------+----+-------------+----+-------+----+----+--------+-----+
# |id|select_type|table|partitions|type|possible_keys|key |key_len|ref |rows|filtered|Extra|
# +--+-----------+-----+----------+----+-------------+----+-------+----+----+--------+-----+
# |1 |SIMPLE     |boys |NULL      |ALL |NULL         |NULL|NULL   |NULL|8   |100     |NULL |
# +--+-----------+-----+----------+----+-------------+----+-------+----+----+--------+-----+

# 增加一条数据

select * from boys ;
# +--+----+---+----+-------+
# |id|name|sex|age |address|
# +--+----+---+----+-------+
# |1 |慕容皝 |男  |22  |NULL   |
# |2 |慕容冲 |男  |33  |NULL   |
# |3 |慕容垂 |男  |44  |NULL   |
# |4 |慕容博 |男  |55  |NULL   |
# |5 |慕容雪 |女  |55  |NULL   |
# |6 |慕容复 |男  |55  |NULL   |
# |7 |慕容龙城|女  |55  |NULL   |
# |8 |慕容吹雪|男  |NULL|NULL   |
# +--+----+---+----+-------+

# 8
select count(*) from boys;
# 8
select count(1) from boys;
# 0
select count(address) from boys;
# 7
select count(age) from boys;








# 题外话: 如果要导出 性别为男生的数据 到另一个表 sql  select * from boys where sex = 男 同时dataGrip 查询结果右上角 extractors(翻译:提取者;抽出器;提取器)
#           改为sql insert 模式 :例子如下:
select * from boys where sex = '男' ;
# 提取器的为 insert sql 后 查询的结果如下:
# INSERT INTO sql_test.boys (id, name, sex, age, address) VALUES (1, '慕容皝', '男', '22', null);
# INSERT INTO sql_test.boys (id, name, sex, age, address) VALUES (2, '慕容冲', '男', '33', null);
# INSERT INTO sql_test.boys (id, name, sex, age, address) VALUES (3, '慕容垂', '男', '44', null);
# INSERT INTO sql_test.boys (id, name, sex, age, address) VALUES (4, '慕容博', '男', '55', null);
# INSERT INTO sql_test.boys (id, name, sex, age, address) VALUES (6, '慕容复', '男', '55', null);

#  建表语句
create table sql_test.boys
(
    id      int                     not null,
    name    varchar(20)             null,
    sex     varchar(20) default '男' null comment '默认男',
    age     varchar(20)             null,
    address int                     null,
    constraint boys_id_uindex
        unique (id)
)
    comment '男生表';

# 用datagrip 查询结果 的 提取器 导出 sql语句
INSERT INTO sql_test.boys (id, name, sex, age, address) VALUES (1, '慕容皝', '男', '22', null);
INSERT INTO sql_test.boys (id, name, sex, age, address) VALUES (2, '慕容冲', '男', '33', null);
INSERT INTO sql_test.boys (id, name, sex, age, address) VALUES (3, '慕容垂', '男', '44', null);
INSERT INTO sql_test.boys (id, name, sex, age, address) VALUES (4, '慕容博', '男', '55', null);
INSERT INTO sql_test.boys (id, name, sex, age, address) VALUES (5, '慕容雪', '女', '55', null);
INSERT INTO sql_test.boys (id, name, sex, age, address) VALUES (6, '慕容复', '男', '55', null);
INSERT INTO sql_test.boys (id, name, sex, age, address) VALUES (7, '慕容龙城', '女', '55', null);
INSERT INTO sql_test.boys (id, name, sex, age, address) VALUES (8, '慕容吹雪', '男', null, null);

 

查看表关系的sql(尤其是在数据量非常大的情况下使用,非常有效)



select * from girl;
# +--+----+------+---+
# |id|name|boy_id|sex|
# +--+----+------+---+
# |1 |黄蓉  |1     |女  |
# |2 |李莫愁 |2     |女  |
# |3 |陆无双 |2     |女  |
# |4 |程英  |3     |女  |
# |5 |周紫墨 |3     |女  |
# |6 |宋小婉 |3     |女  |
# |7 |侯小妹 |3     |女  |
# |8 |小黄蓉 |3     |女  |
# +--+----+------+---+

# 8 有女朋友的男生信息
select count(boys.id) from boys inner join girl on  boys.id = girl.boy_id ;
#  最新认知(重要) :inner join 取交集不是 数目取交集,eg: boys 只有一个 id 为 1 的数据,但是 girl有 8 条 boy_id 为 1 的记录,
#  最后的的结果 数量就是 8,大于 boys 表的一条数据(唯一确定的是小于等于 笛卡尔集 (男生表count*女生表count))
select boys.* from boys inner join girl on  boys.id = girl.boy_id ;
# +--+----+---+---+-------+
# |id|name|sex|age|address|
# +--+----+---+---+-------+
# |1 |慕容皝 |男  |22 |NULL   |
# |2 |慕容冲 |男  |33 |NULL   |
# |2 |慕容冲 |男  |33 |NULL   |
# |3 |慕容垂 |男  |44 |NULL   |
# |3 |慕容垂 |男  |44 |NULL   |
# |3 |慕容垂 |男  |44 |NULL   |
# |3 |慕容垂 |男  |44 |NULL   |
# |3 |慕容垂 |男  |44 |NULL   |
# +--+----+---+---+-------+
# 8
select count(*) from boys inner join girl on  boys.id = girl.boy_id ;

# +--+-----------+-----+----------+------+--------------+--------------+-------+--------------------+----+--------+-----------+
# |id|select_type|table|partitions|type  |possible_keys |key           |key_len|ref                 |rows|filtered|Extra      |
# +--+-----------+-----+----------+------+--------------+--------------+-------+--------------------+----+--------+-----------+
# |1 |SIMPLE     |girl |NULL      |ALL   |NULL          |NULL          |NULL   |NULL                |7   |100     |Using where|
# |1 |SIMPLE     |boys |NULL      |eq_ref|boys_id_uindex|boys_id_uindex|4      |sql_test.girl.boy_id|1   |100     |Using index|
# +--+-----------+-----+----------+------+--------------+--------------+-------+--------------------+----+--------+-----------+

create table girl
(
    id     int         null,
    name   varchar(20) null,
    boy_id int         null,
    sex    varchar(40) null
)
    comment '女性表';

#  给 boy_id 建立索引后

create index girl_boy_id_index
    on sql_test.girl (boy_id);


# 给  boy_id 建立唯一 索引后
# 8
select count(boys.id) from boys inner join girl on  boys.id = girl.boy_id ;
# +--+-----------+-----+----------+------+-----------------+-----------------+-------+--------------------+----+--------+------------------------+
# |id|select_type|table|partitions|type  |possible_keys    |key              |key_len|ref                 |rows|filtered|Extra                   |
# +--+-----------+-----+----------+------+-----------------+-----------------+-------+--------------------+----+--------+------------------------+
# |1 |SIMPLE     |girl |NULL      |index |girl_boy_id_index|girl_boy_id_index|5      |NULL                |7   |100     |Using where; Using index|
# |1 |SIMPLE     |boys |NULL      |eq_ref|boys_id_uindex   |boys_id_uindex   |4      |sql_test.girl.boy_id|1   |100     |Using index             |
# +--+-----------+-----+----------+------+-----------------+-----------------+-------+--------------------+----+--------+------------------------+

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值