Mysql DOC阅读笔记
2016-08-16 13:54
155 查看
Mysql DOC阅读笔记
转自我的GithubSpeed of SELECT Statements
合理利用索引隔离调试查询中花费高的部分,例如函数调用是在结果集中的行执行还是全表中的行执行
最小化全表扫描的数量,特别是在大表中
定期使用
ANALYZE TABLE语句更新表的统计数据,使查询优化器可以做出更合理的优化。
学习各个
存储引擎的特殊调试,索引和配置
优化单条只读查询事务
避免使用难以理解的方式编写QUERY,因为查询优化器可能使用的还是同样的优化决策,不要牺牲SQL的可读性
如果性能问题不能通过基本的
GUIDELINES解决,那么使用
EXPLAIN语句查看更具体的信息
调整MySQL所使用到的用作缓存的内存区域,例如(InnoDB buffer pool, MyISAM key cache, MySQL query cache)
小心处理锁的问题
EXPLAIN Statement
结果字段id: SELECT的标识符
select_type: SELECT的类型
SIMPLE: Simple SELECT (not using UNION or subqueries)
PRIMARY: Outermost SELECT
UNION: Second or later SELECT statement in a UNION
DEPENDENT UNION: Second or later SELECT statement in a UNION, dependent on outer query
UNION RESULTRESULT of a UNION
SUBQUERYFirst SELECT in subquery
DEPENDENT SUBQUERYFirst SELECT in subquery, dependent on outer query.
DERIVEDDerived table SELECT (subquery in FROM clause)
MATERIALIZEDMaterialized subquery
UNCACHEABLE SUBQUERYA subquery for which the result cannot be cached and must be re-evaluated for each row of the outer query
table: The name of the table to which the row of output refers
<unionM,N> M,N为子查询的id
<deriveN> N为子查询的id
<subqueryN> N为子查询的id
partitions: 使用的分区
type: JOIN TYPE
possible_keys: 可选的索引
key: 查询用到的key或者index
key_len: The key_len column indicates the length of the key that MySQL decided to use. The length is NULL if the key column says NULL. Note that the value of key_len enables you to determine how many parts of a multiple-part key MySQL actually uses
ref: The ref column shows which columns or constants are compared to the index named in the key column to select rows from the table.
rows: The rows column indicates the number of rows MySQL believes it must examine to execute the query
filtered: The filtered column indicates an estimated percentage of table rows that will be filtered by the table condition. That is, rows shows the estimated number of rows examined and rows × filtered / 100 shows the number of rows that will be joined with previous tables.
Extra: This column contains additional information about how MySQL resolves the query. See Explain Extra Information
MySQL Index
多列索引,查询条件需要按照列的顺序并且起始列为索引的起始列,中间不能有间隔使用MIN()或者MAX()查询的时候多列索引的使用也遵循最左列的原则,即WHERE中要先使用多列索引中的最左列,那么查询优化器会将MIN()和MAX()做一个key上的扫描,然后将常数的结果进行替换。例如:
SELECT MIN(key_part2),MAX(key_part2) FROM tbl_name WHERE key_part1=10;
LIKE也能使用索引,只要参数是常量,并且不以通配符开头
在不通列的对比中如果要使用索引,需要两个列的数据类型一样,CHAR(10)和VARCHAR(10)被认为是一样的。
多列索引的实现: A multiple-column index can be considered a sorted array, the rows of which contain values that are created by concatenating the values of the indexed columns.
多列索引详情见Multiple Index
Mysql对Where的优化详情见Where Optimization
InnoDB的聚簇索引含有列数据,优先建立组合索引而不是每一列的单独索引。InnoDB的二级索引的叶子节点中存储的是PK,而不是行号。MyISAM的索引是非聚簇索引,叶子节点中是行指针。See more
在where条件中查询条件对索引使用的影响:
Any index that does not span all AND levels in the WHERE clause is not used to optimize the query. In other words, to be able to use an index, a prefix of the index must be used in every AND group. The following WHERE clauses use indexes:
... WHERE index_part1=1 AND index_part2=2 AND other_column=3 /* index = 1 OR index = 2 */ ... WHERE index=1 OR A=10 AND index=2 /* optimized like "index_part1='hello'" */ ... WHERE index_part1='hello' AND index_part3=5 /* Can use index on index1 but not on index2 or index3 */ ... WHERE index1=1 AND index2=2 OR index1=3 AND index3=3; These WHERE clauses do not use indexes: /* index_part1 is not used */ ... WHERE index_part2=1 AND index_part3=2 /* Index is not used in both parts of the WHERE clause */ ... WHERE index=1 OR A=10 /* No index spans all rows */ ... WHERE index_part1=1 OR index_part2=10
buffer pool
buffer pool 是Mysql中用来存放InnoDB的表和索引数据的内存区域, 这些内存区域被划分成页。buffer pool使用使用linked list作为pages的实现。页的交换使用LRU算法,在大内存的系统中,你可以将buffer pool划分成多个buffer pool instances。 innodb_buffer_pool_size中配置的内存大小被所有buffer pool实例所分割,多buffer pool实例更适给Innodb buffer pool划分几个G以上空间的应用,每一个实例都可以得到一个1G或者以上大小的空间。Read-Only Transactions
如果InnoDB可以提前知道一个事务是只读事务,那么它就可以避免使用transaction ID(TRX_ID)。Transaction ID只需要在语句存在更新或者读语句中存在锁的情况中使用。 InnoDB是这样检测只读事务的:事务以START TRANSACTION READ ONLY语句开始,但是这种情况仍可以对session-specific临时表进行更新,因为对这些表进行更新不影响其他事务。
autocommit标志位打开的情况下,所有事务都是一条但语句,那么没有更新的语句将会被包装成只读事务。
事务没有用READ ONLY选项,但是还没有更新语句或者明确的锁语句,这时候事务是一个只读事务,知道遇到了一个明确的锁或者更新语句。 所以,对于查询语句可以将它们放在一个READ ONLY事务中,或者在执行select语句之前打开autocommit选项,或者只是简单的不要吧DML放在DQL中间。
Other
innodb行锁的实现方式
对于innodb的表而言,insert、update、delete等操作虽然都是加行级锁,但这些行锁都是通过给索引上的索引项加锁来实现的,这就意味着:只有通过索引条件检索数据,innodb才能使用行级锁,否则,innodb将使用表级锁。 * 在不通过索引条件检索的时候,innodb使用的是表锁,不是行锁。 例如:create table tab_no_index(id int,name varchar(10)) engion=innodb; create table tab_with_index(id int,name varchar(10),key id_idx(id)) engion=innodb;语句
select * from tab_no_index where id=1 for update;会加表锁,而
select * from tab_with_index where id=1 for update;会加行锁。
虽然访问不同行的记录,但是如果是使用相同的索引键,仍然会出现锁冲突。 例如,上例表tab_with_index中有两条记录为(1,’1’)和(1,’4’),则select * from tab_with_index where id=1 and name=’1’ for update;会对这两条记录都加锁。
当表有多个索引时,不同的事务可以使用不同的索引锁定不同的行。此外,不论是使用主键索引、唯一索引或普通索引,innodb都会使用行锁对数据加锁。
innodb的间隙锁(Next-key锁)
当使用范围条件而不是相等条件检索数据,并请求共享或排他锁时,innodb会给符合条件的已有数据记录的索引项加锁;对于键值在条件范围内但并不 存在的记录,叫做“间隙”,innodb也会对这个“间隙”加锁。例如,emp表中只有101条记录,其中empid为索引键,值分别为 1,2,……,100,101,语句select * from emp where empid>100 for update;不仅会对101记录加锁,还会对empid大于101(这些记录不存在)的“间隙”加锁。相关文章推荐
- 【转】共享对象--FlashCom Develop阅读笔记 4
- 项目管理阅读笔记
- XMPP RFC阅读笔记(一)
- C++ FAQ阅读笔记[2]--引用
- Thinking in C++ 阅读笔记(第一章)
- C++ FAQ阅读笔记[3]--内联函数
- 代码阅读总结之ASP.NET StartKit TimeTracker(QueryString之改进笔记)
- C++ FAQ阅读笔记[1] -- 类与对象
- C++ FAQ阅读笔记[2]--引用
- ZT:项目管理阅读笔记
- (大卫的阅读笔记)More Effective C++ Item 附2:一个auto_ptr的实现实例
- 阅读Flash帮助文件笔记(一)
- XMPP RFC阅读笔记(一)
- FCS阅读笔记:良好的编程习惯
- FCS阅读笔记17 应用程序设计和开发
- 【转】连接示例--FlashCom Develop阅读笔记 2
- 《实现JSP分页显示数据库》的阅读笔记
- XMPP RFC阅读笔记(二)
- ThunderBird, NewsBlog部分代码阅读笔记
- Thinking in C++ 阅读笔记(第三章)