今天最新新闻事件报道上海有实力的seo推广咨询
1、在进行查询时,索引列不能是表达式的一部分,也不能是函数的参数,否则无法使用索引
-  
例如下面的查询不能使用 actor_id 列的索引:
 -  
#这是错误的
 -  
SELECT actor_id FROM sakila.actor WHERE actor_id + 1 = 5;
 -  
优化方式:可以将表达式、函数操作移动到等号右侧。如下:
 -  
SELECT actor_id FROM sakila.actor WHERE actor_id = 5 - 1;
 -  
2、在需要使用多个列作为条件进行查询时,使用多列索引比使用多个单列索引性能更好
-  
例如下面的语句中,最好把actor_id 和 film_id 设置为多列索引。猿辅导有道题,详见链接,可以让理解更深刻。
 -  
SELECT film_id, actor_ id FROM sakila.film_actor
 -  
WHERE actor_id = 1 AND film_id = 1;
 -  
3、让选择性最强的索引列放在前面。 见MySql最左前缀原则 索引的选择性是指:不重复的索引值和记录总数的比值。最大值为 1,此时每个记录都有唯一的索引与其对应。选择性越高,每个记录的区分度越高,查询效率也越高
-  
例如下面显示的结果中 customer_id 的选择性比 staff_id 更高,因此最好把 customer_id 列放在多列索引的前面。
 -  
复制代码
 -  
SELECT COUNT(DISTINCT staff_id)/COUNT(*) AS staff_id_selectivity,
 -  
COUNT(DISTINCT customer_id)/COUNT(*) AS customer_id_selectivity,
 -  
COUNT(*)
 -  
FROM payment;
 -  
#结果如下
 -  
staff_id_selectivity: 0.0001
 -  
customer_id_selectivity: 0.0373
 -  
COUNT(*): 16049
 -  
4、对于 BLOB、TEXT 和 VARCHAR 类型的列,必须使用前缀索引,只索引开始的部分字符。 前缀长度的选取需要根据索引选择性来确定
 -  
5、索引包含所有需要查询的字段的值。具有以下优点: 索引通常远小于数据行的大小,只读取索引能大大减少数据访问量。 一些存储引擎(例如 MyISAM)在内存中只缓存索引,而数据依赖于操作系统来缓存。因此,只访问索引可以不使用系统调用(通常比较费时)。 对于 InnoDB 引擎,若辅助索引能够覆盖查询,则无需访问主索引
 -  
6、mysql在使用like进行模糊查询的时候把%放后面,避免开头模糊查询 因为mysql在使用like查询的时候只有使用后面的%时,才会使用到索引
-  
如:'%ptd_' 和 '%ptd_%' 都没有用到索引;而 'ptd_%' 使用了索引。
 -  
复制代码
 -  
#进行全表查询,没有用到索引
 -  
EXPLAIN SELECT * FROM `user` WHERE username LIKE '%ptd_%';
 -  
EXPLAIN SELECT * FROM `user` WHERE username LIKE '%ptd_';
 -  
#有用到索引
 -  
EXPLAIN SELECT * FROM `user` WHERE username LIKE 'ptd_%';
 -  
复制代码
 -  
再比如:经常用到的查询数据库中姓张的所有人:
 -  
SELECT * FROM `user` WHERE username LIKE '张%';
 -  
7、在表中建立索引,优先考虑where、group by使用到的字段
 -  
8、 尽量避免使用in 和not in,会导致数据库引擎放弃索引进行全表扫描
-  
比如:
 -  
SELECT * FROM t WHERE id IN (2,3)
 -  
SELECT * FROM t1 WHERE username IN (SELECT username FROM t2)
 -  
优化方式:如果是连续数值,可以用between代替。如下:
 -  
SELECT * FROM t WHERE id BETWEEN 2 AND 3
 -  
如果是子查询,可以用exists代替。如下:
 -  
SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 WHERE t1.username = t2.username)
 -  
9、尽量避免使用or,会导致数据库引擎放弃索引进行全表扫描
-  
如:
 -  
SELECT * FROM t WHERE id = 1 OR id = 3
 -  
优化方式:可以用union代替or。如下:
 -  
SELECT * FROM t WHERE id = 1
 -  
UNION
 -  
SELECT * FROM t WHERE id = 3
 -  
10、 尽量避免进行null值的判断,会导致数据库引擎放弃索引进行全表扫描
-  
SELECT * FROM t WHERE score IS NULL
 -  
优化方式:可以给字段添加默认值0,对0值进行判断。如下:
 -  
SELECT * FROM t WHERE score = 0
 -  
11、尽量避免在where条件中等号的左侧进行表达式、函数操作,会导致数据库引擎放弃索引进行全表扫描
-  
例如:
 -  
SELECT * FROM t2 WHERE score/10 = 9
 -  
SELECT * FROM t2 WHERE SUBSTR(username,1,2) = 'li'
 -  
优化方式:可以将表达式、函数操作移动到等号右侧。如下:
 -  
SELECT * FROM t2 WHERE score = 10*9
 -  
SELECT * FROM t2 WHERE username LIKE 'li%'
 
 -  
 
 -  
 -  
12、当数据量大时,避免使用where 1=1的条件。通常为了方便拼装查询条件,我们会默认使用该条件,数据库引擎会放弃索引进行全表扫描
-  
SELECT * FROM t WHERE 1=1
 -  
优化方式:用代码拼装sql时进行判断,没where加where,有where加and。
 
 -  
 -  
13、建立索引后,查询时不会扫描全表,而会查询索引表锁定结果
 -  
14、在数据库进行DML操作的时候,除了维护数据表之外,还需要维护索引表,运维成本增加
 -  
15、选用选择性高的字段作为索引,一般unique的选择性最高
 -  
16、复合索引:选择性越高的排在越前面。(左前缀原则);
 -  
17、如果查询条件中两个条件都是选择性高的,最好都建索引
 -  
18、 数据类型出现隐式转换时也不会使用索引
-  
让我们对上一个例子中的表增加一个 AGE 索引。
 -  
CREATE TABLE `test_index_table` (
 -  
`id` int(11) NOT NULL AUTO_INCREMENT,
 -  
`name` varchar(45) DEFAULT NULL,
 -  
`birthday` datetime DEFAULT NULL,
 -  
`address` varchar(45) DEFAULT NULL,
 -  
`phone` varchar(45) DEFAULT NULL,
 -  
`note` varchar(45) DEFAULT NULL,
 -  
`age` varchar(11) DEFAULT NULL,
 -  
PRIMARY KEY (`id`),
 -  
KEY `NAME_ADDRESS` (`name`,`id`) USING BTREE,
 -  
KEY `AGE` (`age`) USING BTREE
 -  
) ENGINE=InnoDB AUTO_INCREMENT=283 DEFAULT CHARSET=utf8
 -  
尝试使用下面的 sql 语句进行查询
 -  
explain SELECT * FROM test.test_index_table where age = 26
 -  
由于表中的 age 是 VARCHAR 类型。而在 sql 语句中我们使用的是数字类型 26。MYSQL 默认会把输入的常量值进行转换以后才进行检索。现在我们通过 explain 看看这个语句的分析结果
 
 -  
 -  
19、查看索引使用情况
-  
show status like 'handler_read%';
 
 -  
 -  
20、mysql查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。 因此数据库默认排序可以符合要求的情况下不要使用排序操作,尽量不要包含多个列的排序,如果需要最好给这些列建复合索引
 
 -  
 
 -  
 
 -  
 
 -  
 
 -  
 
