原因:
(1)、查询语句写的烂
(2)、索引失效:索引分为单值索引和多值索引
单值索引:
create index idx_user_name on user(name);
多值索引:
create index idx_user_nameEmail on user(name,email);
(3)、关联查询太多join(设计缺陷或不得已的需求;
(4)、服务器调优及各个参数设置(缓冲\线程数等)。
二、常见的Join查询
1、SQL的执行顺序:
手写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
SELECT DISTINCT <select_list> FROM <left_table><join_type> JOIN <right_table>ON<join_condition> WHERE <where_condition> GROUP BY <group_by_list> HAVING <having_condotion> ORDER BY <order_by_condotion> LIMIT <limit_number>
机读:
1 2 3 4 5 6 7 8 9 10
FORM <left_table> ON <join_condition> <join_type> JOIN <right_type> WHERE <where_condition> GROUP BY <group_by_list> HAVING <having_condition> SELECT DISTINCT <select_list> ORDER BY <order_by_condition> LIMIT <limit_number>
2、join图
两张表:tbl_dept
tbl_emp:
查询结果:
中: select * from tbl_emp a inner join tbl_dept b on a.deptId=b.id;
左上:select * from tbl_emp a left join tbl_dept b on a.deptId=b.id;
右上:select * from tbl_emp a right join tbl_dept b on a.deptId=b.id;
左中:select * from tbl_emp a left join tbl_dept b on a.deptId=b.id where b.id is null;
右中:select * from tbl_emp a right join tbl_dept b on a.deptId=b.id where a.deptId is null;
左下: select * from tbl_emp a left join tbl_dept b on a.deptId=b.id ;
右下:SELECT * FROM tbl_emp a LEFT JOIN tbl_dept b ON a.deptId=b.id WHERE b.id IS NULL
UNION
SELECT * FROM tbl_emp a RIGHT JOIN tbl_dept b ON a.deptId=b.id WHERE a.`deptId` IS NULL ;
我们平时所说的索引,如果没有特别指明,都是指B树(多路搜索树,并不一定是二叉树)结构组织的索引。其中聚集索引,次要索引,覆盖索引,
复合索引,前缀索引,唯一索引默认都是使用B+树索引,统称索引。当然,除了B+树这种类型的索引之外,还有哈希索引(hash index)等。
2、索引的优势
(1)、类似大学图书馆建书目索引,提高数据检索效率,降低数据库的IO成本;
(2)、通过索引列对数据进行排序,降低数据排序成本,降低了CPU的消耗;
3、索引的劣势
(1)、实际上索引也是一张表,该表保存了主键和索引字段,并指向实体表的记录,所以索引列也是要占用空间的;
(2)、虽然索引大大提高了查询速度,同时却会降低更新表的速度,如果对表INSERT,UPDATE和DELETE。因为更新表时,MySQL不仅要不存数据,
还要保存一下索引文件每次更新添加了索引列的字段,都会调整因为更新所带来的键值变化后的索引信息;
(3)、索引只是提高效率的一个因素,如果你的MySQL有大数据量的表,就需要花时间研究建立优秀的索引,或优化查询语句;
4、索引的分类
(1)、单值索引:
即一个索引只包含单个列,一个表可以有多个单列索引。建议一张表索引不要超过5个,优先考虑复合索引。
(2)、唯一索引:
索引列的值必须唯一,但允许有空值。(unique key)
(3)、复合索引,即一个索引包含多个列。
基本语法:
(1)、创建
创建表时添加索引:
CREATE [UNIQUE] INDEX indexName ON mytable(columnname(length));
修改表时添加索引:
ALTER mytable ADD [UNIQUE] INDEX [indexName] ON(columnname(length));
(2)、删除索引
DROP INDEX [indexName] ON mytable;
(3)、查看索引
SHOW INDEX FROM table_name\G
(4)有四种方式来添加数据表的索引
ALTER TABLE tbl_name ADD PRIMARY KEY(column_list)#该语句添加一个主键,这意味着索引值必须是唯一的,且不能为空
ALTER TABLE tbl_name ADD UNIQUE index_name(column_list)#这条语句创建的索引值必须是唯一的(除NULL除外,NULL可能会多次出现)
ALTER TABLE tbl_name ADD INDEX index_name(column_list)#添加普通值索引,索引值可能出现多次
ALTER TABLE tbl_name ADD FULLTEXT index_name(column_list)#该语句指定索引为fulltext,用于全文索引.
5、mysql索引结构
(1)、BTree索引