通过explain可以知道mysql是如何处理语句的,其实就是在干查询优化器的事。语句:EXPLAIN+sql查询语句
注:一般需要达到 ref、eq_ref 级别,范围查找需要达到 range
合理的数据库结构不仅可以使数据库占用更小的磁盘空间,而且能够使查询速度更快。数据库结构的设计,需要考虑数据冗余、查询和更新的速度、字段的数据类型是否合理等多方面的内容
1、星形模型(Star Schema)和雪花模型(SnowflakeSchema)的模型选择
2、增加中间表
对于需要经常联合查询的表,可以建立中间表以提高查询效率
3、优化数据类型
Mysql常用数据类型存储大小及范围:
Mysql常用数据类型存储大小及范围_葫芦胡的博客-CSDN博客_mysql最大的存储类型4、表设计不能有太多的列,数千的列会影响性能
5、关联操作设计的表不要太多,否则执行会很慢
mysql限制了每个关联操作最多只能有61张表,在实际应用中,经验法则得出关联操作的表数量最好控制在12个以内
6、扩展:范式和反范式
范式主要优化的是增删改的性能,比如数据冗余、更新异常、删除异常等。绝对的范式化是实验室中的产物,在实际的应用中要混用范式化和反范式化,根据具有情况,往往会带来较高的查询效率
遵循数据库的范式要求,尤其是前三个范式。严格遵循范式设计的表通常更小、数据冗余少,做更新操作简单快捷,但是,唯一的缺点就是在做查询时需要表关联,关联查询会不仅会带来高的代价,而且还可能造成索引策略失效,导致更低效率的查询
索引应该是对查询性能优化最有效的手段了,它能够轻易地将查询效率提高几个数量级
4.2.1 Mysql索引类型
索引总结:
--查看表索引:
show index from 【table】
--直接创建索引
CREATE INDEX indexName ON table(column(length))
-- 修改表结构的方式添加索引
ALTER tableADD INDEX indexName ON (column(length))
--主键索引
ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )
--唯一索引
ALTER TABLE `table_name` ADD UNIQUE (`column` )
--普通索引
ALTER TABLE `table_name` ADD INDEX index_name ( `column`(length) )
--复合索引
ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
index_name ON table_name;
--length的确定:
如果索引列长度过长,这种列索引时将会产生很大的索引文件,不便于操作,可以使用前缀索引方式进行索引,前缀索引应该控制在一个合适的点,控制在0.31黄金值即可(大于这个值就可以创建)。
SELECT COUNT(DISTINCT(LEFT(`title`,10)))/COUNT(*) FROM Arctic; -- 这个值大于0.31就可以创建前缀索引,Distinct去重复
--删除索引:
1)ALTER TABLE table_name DROP INDEX index_name
2)DROP INDEX
4.2.2 索引的缺点
虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行insert、update和delete。因为更新表时,不仅要保存数据,还要保存一下索引文件
建立索引会占用磁盘空间的索引文件。一般情况这个问题不太严重,但如果你在一个大表上创建了多种组合索引,索引文件的会增长很快
4.2.3 索引的注意事项
当B表的数据集比A表小时,用in优化 exist两表执行顺序是先查B表再查A表查询语句:SELECT * FROM A WHERE id in (SELECT id FROM B) ;
当A表的数据集比B表小时,用exist优化in ,两表执行顺序是先查A表,再查B表,查询语句:SELECT * FROM A WHERE EXISTS (SELECT id FROM B WHERE A.id=B.ID) ;
优化的方法可以取前一页的最大行数的id,然后根据这个最大的id来限制下一页的起点。比如此列中,上一页最大的id是866612。
select id,name from product where id> 866612 limit 20
? sort-buffer-size/join-buffer-size / read-rnd-buffer-size,4~8MB为宜
?optimizer_switch=“index_condition_pushdown=on,mrr=on,mrr_cost
_based=off,batched_key_access=on”
? tmp-table-size=max-heap-table-size,100MB左右为宜
? log-queries-not-using-indexes & log_throttle_queries_not_using_indexes
如何选择:
1. 是否要支持事务,如果要请选择 InnoDB,如果不需要可以考虑 MyISAM;
2. 如果表中绝大多数都只是读查询,可以考虑 MyISAM,如果既有读写也挺频繁,请使用InnoDB。
3. 系统奔溃后,MyISAM恢复起来更困难,能否接受,不能接受就选 InnoDB;
4. MySQL5.5版本开始Innodb已经成为Mysql的默认引擎(之前是MyISAM),说明其优势是有目共睹的。如果你不知道用什么存储引擎,那就用InnoDB,至少不会差