Mysql:count(*),orderBy

count(*) 计数

myIsam count(*)很快,因为是直接保存的数目,但是加了where就不能很快返回了

InnoDB因为MVCC(单行多版本)的问题不适合计数,所以不能快速返回总数目

1.快速count(*)
1.使用缓存计数问题
1.缓存会丢失
2.数据不准确
2.在数据库保存计数
使用事务可以解决缓存问题

计数效率比较
count()>=count(1)>count(id)>count(字段)
count(
):被mysql优化过
尽量使用count(*)

redolog -binLog 两阶段提交

新行更新到内存
-> 写入redo log 处于prepare状态
-> 写入bin log
->提交事务,处于commit状态

redolog 是innodb特有日志,主要作用是崩溃恢复,但是由于循环
binLog 是mysql自有日志,支持日志归档
order by
CREATE TABLE `t` ( `id` int(11) NOT NULL, `city` varchar(16) NOT NULL,
        `name` varchar(16) NOT NULL,
        `age` int(11) NOT NULL, 
        `addr` varchar(128) DEFAULT NULL,
        PRIMARY KEY (`id`), KEY `city` (`city`) 
        ) ENGINE=InnoDB;

select city,name,age from t where city='杭州' order by name limit 1000  ;

全字段排序
1.sort_buffer初始化,确定放入所需字段
2.使用二级索引查询第一个符合条件的数据,从索引中获取主键
3.通过主键索引获取所需字段,放入sort_buffer
4.再次进入二级索引,查找符合要求下一个
5.重复3,4,查出所有符合要求的值
6.在sort_buffer中快速排序
7.(如果需要)分页

rowid排序
如果单行查询长度太大,mysql会使用另一种排序

1.sort_buffer初始化,确定放入所需字段
2.使用二级索引查询第一个符合条件的数据,从索引中获取主键
3.通过主键索引获取**主键和排序字段**,放入sort_buffer
4.再次进入二级索引,查找符合要求下一个
5.重复3,4,查出所有符合要求的值
6.在sort_buffer中快速排序
7.回表,使用id取出全部所需字段
8.(如果需要)分页

对于 InnoDB 表来说,rowid 排序会要求回表多造成磁盘读,因此不会被优先选择。

优化建议

1.不要对字段进行计算
select * from tradelog where id + 1 = 10000;
select count(*) from tradelog where month(t_modified)=7;

2.隐式类型转换
//判断mysql怎么进行数据类型转换,下面的字符串会转成数字,返回1
select “10” > 9;

3.隐式字符编码转换

两张表编码格式不一致也会导致全表查询。

为什么有些只查一行的数据,还是很慢

等MDL锁(在DDL和DML操作保持一致的锁)

等flush

等行锁

为什么有些只查一行的数据,还是很慢
    (等元数据锁,等行锁,等flaush,没有索引)

脏读:一个事务读取到另一个未曾提交事务的数据
不可重复读:一个事务多次查询同一数据,得到的数据不一致
幻读:一个事务多次查询数据,后面查询得到前面未得到的数据

你可能感兴趣的:(Mysql:count(*),orderBy)