标签:das mysql查询 相关 mysql数据库 between 碎片 外部 内存碎片 额外信息
通过show variables like "%query_cache%"
查看与查询缓存相关的参数:
mysql> show variables like "%query_cache%";
+------------------------------+---------+
| Variable_name | Value |
+------------------------------+---------+
| have_query_cache | YES |
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 1024 |
| query_cache_size | 3145728 |
| query_cache_type | OFF |
| query_cache_wlock_invalidate | OFF |
+------------------------------+---------+
6 rows in set (0.02 sec)
query_cache_type
设置为多少都不起作用。但Query Cache有如下规则,如果数据表被更改,那么和这个数据表相关的全部Cache全部都会无效,并删除。这里“数据表更改”包括: INSERT, UPDATE, DELETE, TRUNCATE, ALTER TABLE, DROP TABLE, or DROP DATABASE
等。如果你的数据表更新频繁的话,那么Query Cache将会成为系统的负担。如果你的应用对数据库的更新很少,那么Query Cache将会作用显著。
参考:理解MySQL数据库查询缓存以及Query Cache,看上去很美
在任意的SELECT查询语句的前面加上EXPLAIN
这个词,就可以分析MySQL在执行该语句时的具体信息:
# 示例1
mysql> explain select 1\G
*************************** 1. row ***************************
id : 1
select_type : SIMPLE
table : NULL
type : NULL
possible_keys: NULL
key : NULL
key_len : NULL
ref : NULL
rows : NULL
Extra : No tables used
1 rows in set (0.05 sec)
# 示例2
mysql> explain select dept_name from hr_department d left join hr_person p on p.dept_id=d.dept_id;
+----+-------------+-------+------+---------------+------+---------+------+------+----------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------------------------------------------+
| 1 | SIMPLE | d | ALL | NULL | NULL | NULL | NULL | 541 | NULL |
| 1 | SIMPLE | p | ALL | NULL | NULL | NULL | NULL | 561 | Using where; Using join buffer (Block Nested Loop) |
+----+-------------+-------+------+---------------+------+---------+------+------+----------------------------------------------------+
2 rows in set (0.05 sec)
# 示例3
mysql> explain select dept_name from hr_department union select dept_name from hr_department_copy;
+----+--------------+--------------------+------+---------------+------+---------+------+------+-----------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------+--------------------+------+---------------+------+---------+------+------+-----------------+
| 1 | PRIMARY | hr_department | ALL | NULL | NULL | NULL | NULL | 541 | NULL |
| 2 | UNION | hr_department_copy | ALL | NULL | NULL | NULL | NULL | 540 | NULL |
| NULL | UNION RESULT | <union1,2> | ALL | NULL | NULL | NULL | NULL | NULL | Using temporary |
+----+--------------+--------------------+------+---------------+------+---------+------+------+-----------------+
3 rows in set (0.08 sec)
在EXPLAIN
的结果行是以MySQL实际执行的查询部分的顺序出现的。
各参数含义:
SIMPLE
(不包括子查询和UNION
)。如果是复杂类型,则最外层标记为PRIMARY
,其他部分标记如下:
SUBQUERY
:表示不在FROM
子句中的子查询DERIVED
:表示在FROM
子句中的子查询UNION
:表示在UNION
中的第二个以及随后的SELECTUNION RESULT
:表示在UNION
的临时表检索结果的SELECTSUBQUERY
和UNION
还可以标记为DEPENDENT
(意味着SELECT依赖与外层查询中发现的数据)和UNCACHEABLE
。ALL
:全表扫描,按从第一行到最后一行的顺序去查找需要的行。index
:与全表扫描一样,只是MySQL扫描表时按照索引次序进行而不是行。range
:范围扫描,就是一个有限制的索引扫描,这比全索引扫描要好,因为不用遍历全部索引,主要是带有BETWEEN
和WHERE
子句里含有>
的查询。ref
:索引访问,也叫索引查找,它返回所有匹配某个单个值的行,但有可能会返回多个符合条件的行,因此,它是查找和扫描的结合体,只有使用非唯一索引或者唯一索引的非唯一性前缀时才会发生。ref_or_null
是ref
的变种,它表示MySQL必须在初次查找的结果里进行第二次查找以找出NULL
条目。eq_ref
:使用这种索引查找,意味着MySQL知道最多只返回一条符合条件的记录。MySQL使用主键或者唯一索引查找时会看到该类型。const, system
:当MySQL能对查询的某部分进行优化并将其转换为一个常量时,就会使用该访问类型。NULL
:这种访问类型意味着MySQL能在优化阶段分解查询语句,在执行阶段甚至用不着再访问表或者索引。例如,从一个索引列里选取最小值就可以通过单独查找索引来完成,不需要再去访问表。possible_keys
中,那么MySQL可能选择了一个覆盖索引。Using index
:表示MySQL将使用覆盖索引,以避免访问表。不要把覆盖索引和index
访问类型弄混了。Using where
:表示MySQL将在存储引擎检索行后再进行过滤,不是所有带有WHERE子句的查询都会显示Using where
。Using temporary
:表示MySQL在对查询结果排除时会使用一个临时表。Using filesort
:表示MySQL会对结果使用一个外部索引排序,而不是按照索引次序从表里读取行。参考:《高性能MySQL》
索引并不一定就是给主键或是唯一的字段。如果在你的表中,有某个字段你总要会经常用来做搜索,那么,请为其建立索引吧。
一些注意点:
①在Join表的时候使用相当类型的例,并将其索引
SELECT company_name FROM users
LEFT JOIN companies ON (users.state = companies.state)
WHERE users.id = xxx
此时,两个 state 字段应该是被建过索引的,而且应该是相当的类型,相同的字符集。
②业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引。
③在 varchar 字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区分度决定索引长度即可。
④根据最左原则,不要使用%xxx%
或%xxx
的形式,而是xxx%
,只有这个才会使用索引(当前前提是该字段创建了索引)。
⑤利用覆盖索引来进行查询操作,避免回表。能够建立索引的种类:主键索引、唯一索引、普通索引,而覆盖索引是一种查询的一种 效果,用explain的结果,extra列会出现:using index。
⑥建组合索引的时候,区分度最高的在最左边。
参考:阿里巴巴Java开发手册v1.2.0
NULL columns require additional space in the row to record whether their values are NULL.
For MyISAM tables, each NULL column takes one bit extra, rounded up to the nearest byte.
①select * from A where exists (select * from B where B.id = A.id);
②select * from A where A.id in (select id from B);
①的执行可以表述为
对外表A中所有记录进行循环,每次循环中对内表B进行查询(如果当前行符合子条件,则选出),主要使用B中的索引。
参考:数据库性能优化之SQL语句优化、深入研究mysql exists与in的性能及效率
全文思路参考
MYSQL性能优化的最佳20+条经验
20180226--更新对explain
中id
的解释
标签:das mysql查询 相关 mysql数据库 between 碎片 外部 内存碎片 额外信息
原文地址:https://www.cnblogs.com/xiaoshen666/p/11258592.html