本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/10

在索引中完成排序

SELECT thread_id FROM thread_5 WHERE id = 11074781 AND status = 0 AND thread_type = 0 ORDER BY post_time LIMIT 0, 50

增加在id 、status、thread_type 、post_time上的4字段复合索引。

原因:通过优化前后的执行计划对比可发现,优化后消除了filesort,直接利用索引的有序性避开额外的排序操作



对filesort的解释:

当不能使用索引生成排序结果的时候,MYSQL需要自己进行排序,如果数据量小则在内存中进行,如果数据量则需要使用磁盘,不过MYSQL将这个过程统一称为文件排序(filesort),即使完全是内存排序不需要任何磁盘文件时也是如此。

如果需要排序的数据量小于排序缓冲区,MYSQL使用内存进行快速排序操作,如果内存不够排序,那么MYSQL会先将数据分块,对独立的块使用快速排序进行排序,并将各个块的排序结果放在磁盘上,然后将各个排序好的块进行合并,最后返回排序结果。

MYSQL有2中排序算法:(不再赘述2种排序的意思)

2次排序传输

单次排序传输

MYSQL在进行文件排序的时候需要使用的临时存储空间可能比想象的大许多。因为MYSQL在排序时,对每一个排序记录都会分配一个足够长的定长空间来存放。这个定长空间必须足够长以容纳最长的字符串。

在关联查询的时候如果需要排序,MYSQL会分为2中情况来处理:如果order by子句的所有列都来自关联的第一个表,那么MYSQL在关联处理第一个表的时候就进行文件排序,Explain的结果可以看到Extra字段有using filesort。除此之外的情况,MYSQL将关联的结果放到一个临时表中,然后在所有关联结束之后,再进行文件排序。Extra的结果时using temporary;using filesort。如果有limit,也在排序之后应用,所以即使返回较少的数据,也会非常耗时。

引用自:http://s.petrunia.net/blog/?p=24





合理建立索引

SELECT c.cust_id cust_id FROM tb_aband_cust_contact c, tb_aband_phone p WHERE c.contact_id = contact_or_recipId AND p.full_phone=88123121 AND c.del_flag=0 AND p.flag=0 AND p.del_flag=0;

建立full_phone、flag、del_flag上的3字段复合索引

MYSQL一次查询只能使用一个索引

分片查询

DELETE FROM mydownload WHERE create_time<1271913480;

建立基于create_time的索引,并使用LIMIT修改为分批的执行,减少锁的时间。

DELETE FROM mydownload WHERE create_time<1271913480 LIMIT 50000

删除操作不会重新整理整个表,只是把行标记为删除,在表中留下“空洞”。

尽管MyISAM是表级锁,但是依然可以一边读取,一边并发追加新行。这种情况下只能读取到查询开始时的所有数据,新插入的数据时不可见的。这样可以避免不一致读。

然而表中间的数据变动的话,还是难以提供一致读。MVCC是解决这个问题的最流行的办法。可是MyISAM不支持MVCC,除非插入操作在表的末尾,否则不能支持并发插入。

通过配置concurrent_insert变量,可以配置MyISAM打开并发插入

0:不允许并发插入,所有插入都会对表加互斥锁。

1:只要表中没有空洞,MyISAM就允许并发插入

2:5.0及以后,强制插入到表的末尾,即使表中有空洞。如果没有线程从表中读取数据,MySQL将把新行放在空洞里。

MyISAM存储引擎的读锁和写锁是互斥的,读写操作是串行的。那么,一个进程请求某个 MyISAM表的读锁,同时另一个进程也请求同一表的写锁,MySQL如何处理呢?答案是写进程先获得锁。不仅如此,即使读请求先到锁等待队列,写请求后 到,写锁也会插到读锁请求之前!这是因为MySQL认为写请求一般比读请求要重要。

max_write_lock_count:

缺省情况下,写操作的优先级要高于读操作的优先级,即便是先发送的读请求,后发送的写请求,此时也会优先处理写请求,然后再处理读请求。这就造成一个问题:一旦我发出若干个写请求,就会堵塞所有的读请求,直到写请求全都处理完,才有机会处理读请求。此时可以考虑使用max_write_lock_count:

max_write_lock_count=1

有了这样的设置,当系统处理一个写操作后,就会暂停写操作,给读操作执行的机会。

low-priority-updates:

我们还可以更干脆点,直接降低写操作的优先级,给读操作更高的优先级。

low-priority-updates=1

mysql 普通日志与慢速日志

http://www.cnblogs.com/coser/archive/2011/11/08/2241674.html

mysql子查询

http://www.cnblogs.com/zhengyun_ustc/archive/2013/11/29/slowquery3.html

依赖子查询

select_type为DEPENDENT SUBQUERY,子查询的第一个select依赖外部的查询。

mysql replace into与on duplicate key update区别

replace没有保留旧值,而on duplicate key update类似于update,保留了旧值

Handler_%

http://www.path8.net/tn/archives/5613

http://blog.itpub.net/26250550/viewspace-1076292/

http://dev.mysql.com/doc/refman/5.0/en/server-status-variables.html

http://www.fromdual.com/mysql-handler-read-status-variables

个人理解:

Handler_read_first:从头到尾扫描一个索引的次数

Handler_read_key:访问索引的次数

Handler_read_last:从尾到头扫描一个索引的次数

Handler_read_next:按照索引的顺序读取下一行次数,经常发生在范围查找或者扫描索引的情况中。

Handler_read_prev:按照索引的顺序读取前一行次数,经常发生在ORDER BY ... DESC

Handler_read_rnd:这个变量比较费解。。。,手册中说:

The number of requests to read a row based on a fixed position. This value is high if you are doing a lot of queries that require sorting of the result. You probably have a lot of queries that require MySQL to scan entire tables or you have joins that do not use keys properly.

全表扫描该值不会增加,不利用索引的排序也不会增加,只有在临时表中进行排序该值才会增加。

Handler_read_rnd_next:从数据文件中读取下一行的次数。

最后两个值应该越大越不好。

权限管理

select user(),current_user()

user()函数会返回当前用户连接到服务器使用的连接参数。

current_user()会返回从权限表中选择的与访问权限相关的用户名和主机名对

user表排序规则

user表排序工作如下,假定user表看起来像这样:

+-----------+----------+-

| Host | User | …

+-----------+----------+-

| % | root | …

| % | jeffrey | …

| localhost | root | …

| localhost | | …

+-----------+----------+-

当服务器读取表时,它首先以最具体的Host值排序。主机名和IP号是最具体的。'%'意味着“任何主机”并且是最不特定的。有相同Host值的条目首先以最具体的User值排序(空User值意味着“任何用户”并且是最不特定的)。最终排序的user表看起来像这样:

+-----------+----------+-

| Host | User | …

+-----------+----------+-

| localhost | root | … ...

| localhost | | … ...

| % | jeffrey | … ...

| % | root | … ...

+-----------+----------+-

当客户端试图连接时,服务器浏览排序的条目并使用找到的第一匹配。对于由jeffrey从localhost的连接,表内有两个条目匹配:Host和User值为'localhost'和''的条目,和值为'%'和'jeffrey'的条目。'localhost'条目首先匹配,服务器可以使用。

权限更改何时生效

mysqld启动时,所有授权表的内容被读进内存并且从此时生效。

当服务器注意到授权表被改变了时,现存的客户端连接有如下影响:

表和列权限在客户端的下一次请求时生效。

数据库权限改变在下一个USE db_name命令生效。

全局权限的改变和密码改变在下一次客户端连接时生效。

如果用GRANT、REVOKE或SET PASSWORD对授权表进行修改,服务器会注意到并立即重新将授权表载入内存。

如果你手动地修改授权表(使用INSERT、UPDATE或DELETE等等),你应该执行mysqladmin flush-privileges或mysqladmin reload告诉服务器再装载授权表,否则你的更改将不会生效,除非你重启服务器。

如果你直接更改了授权表但忘记重载,重启服务器后你的更改方生效。这样可能让你迷惑为什么你的更改没有什么变化!

查看授权

当你修改授权表的内容时,确保你按你想要的方式更改权限设置是一个好主意。要检查给定账户的权限,使用SHOW GRANTS语句。例如,要检查Host和User值分别为pc84.example.com和bob的账户所授予的权限,应通过语句:

mysql> SHOW GRANTS FOR 'bob'@'pc84.example.com';

一个有用的诊断工具是mysqlaccess脚本,由Carlier Yves 提供给MySQL分发。使用--help选项调用mysqlaccess查明它怎样工作。注意:mysqlaccess仅用user、db和host表检查存取。它不检查tables_priv、columns_priv或procs_priv表中指定的表、列和程序级权限。

EXPLAIN Impossible WHERE noticed after reading const tables

mysql> explain select * from recent_answer where id=7;

+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+

| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+

| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE noticed after reading const tables |

+----+-------------+-------+------+---------------+------+---------+------+------+-----------------------------------------------------+

mysql实际访问一遍primary key或者unique key(sql语句必须用到了primary key或者unique key),发现没有这条记录,返回Impossible WHERE noticed after reading const tables

查看事务锁

常用查看锁的方式

show engine innodb status

没有明确指出谁持有锁,但是可以显示出事务在等待锁

innoodb_locks

当前出现的锁,但是无法得出哪个事务持有锁,哪个事务等待锁

innodb_lock_waits

显示哪个事务持有锁,哪个事务等待锁,但是无法显示正在阻塞中的事务的MySQL进程ID

innodb_trx

可以查看MySQL进程的ID

查看死锁信息

show engine innodb status

查找LATEST DETECTED DEADLOCK

关注WAITING FOR THIS LOCK TO BE GRANTED(事务在等待哪个锁)和HOLDS THIS LOCKS(阻塞事务的锁的信息)

元数据锁

当事务开始时,它会获取所有需要使用的表上的元数据锁,并在事务结束后释放锁,所有其他想要修改这些表定义的线程都需要等待事务结束。(5.5.3版本之后)

http://blog.itpub.net/26250550/viewspace-1071987/

innodb_autoinc_lock_mode

翻译自:http://dev.mysql.com/doc/refman/5.1/en/innodb-auto-increment-handling.html

不同的插入

简单插入

插入的行数会被提前计算出来

例如:不包括嵌套子查询的insert和replace

块插入

插入的行数不会被提前计算出来

例如:INSERT ... SELECT, REPLACE ... SELECT, LOAD DATA

复杂模式的插入

包括:在插入时指定自增列的值

INSERT INTO t1 (c1,c2) VALUES (1,'a'), (NULL,'b'), (5,'c'), (NULL,'d'); //c1是自增列

INSERT ... ON DUPLICATE KEY UPDATE,可能分配给该语句的值没有被用到(更新)

innodb_autoinc_lock_mode不同取值

0("traditional” lock mode)

表锁

1("consecutive” lock mode)

“块插入”使用表锁。

简单插入仅锁定分配自增值的过程,一次性分配所需的数量

2("interleaved lock mode)

均不使用表锁,仅锁定分配自增值的过程。

仅能保证唯一并且单调自增,但是不保证连续。

但是可能会造成主从不一致。

Index Merge

explain extended

http://dev.mysql.com/doc/refman/5.1/en/explain-extended.html

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. Before MySQL 5.7.3, this column is displayed if you use EXPLAIN EXTENDED. As of MySQL 5.7.3, extended output is enabled by default and the EXTENDED keyword is unnecessry.

A LEFT JOIN B ON 条件表达式

要想过滤掉A中的数据,必须使用where,即使on中包含有A表中的列的限制条件,也不会过滤A的任何数据

Created_%

Created_tmp_disk_tables:在磁盘上建立临时表的次数。如果无法在内存上建立临时表,MySQL则将临时表建立到磁盘上。内存临时表的最大值是tmp_table_size和max_heap_table_size values中偏小的那个。

Created_tmp_files:MySQL建立的临时文件。

Created_tmp_tables:建立临时表的数目。另外,每当执行 SHOW STATUS,都会使用一个内部的临时表,Created_tmp_tables的全局值都会增加。

NLJ BNL MRR

ICP

翻译自:http://dev.mysql.com/doc/refman/5.6/en/index-condition-pushdown-optimization.html

ICP应用的场合是当MySQL利用索引获取表数据。在没有ICP时,存储引擎利用索引定位数据,将数据返回给服务器,在服务器端利用where条件过滤数据。当ICP启用时,MySQL可以在索引端利用where条件过滤不需要的数据,不需要在服务器端过滤。

MySQL只有当type值为range、 ref、 eq_ref或者ref_or_null并且需要去表中取数据时才会用到ICP(在MySQL5.6中分区表不能使用ICP,在5.7中修复)。当表是InnoDB时,索引必须是二级索引(一级索引可以直接取数据,不必去表中取数据)

ICP是默认开启的,通过设置optimizer_switch变量里的index_condition_pushdown 标记来开启ICP

mysql > set optimizer_switch=’index_condition_pushdown=on|off

假设有一张表,有如下索引:key(zipcode, lastname, firstname),sql语句如下:

SELECT * FROM people WHERE zipcode='95054' AND lastname LIKE '%etrunia%' AND address LIKE '%Main Street%';

如果没有ICP,会在表中扫描所有zipcode='95054'的用户,索引不会帮助过滤不符合lastname LIKE '%etrunia%'的行。当启用ICP时,MySQL会在索引中过滤lastname LIKE '%etrunia%'的行(个人认为可以从explain的key_len字段看出来是否使用了lastname字段来过滤),减少了IO操作

取自http://s.petrunia.net/blog/?p=101 的一张图,其实看了这张图就知道ICP是干嘛的了:

ICP BUG

Foreground and Background Threads

前台线程的程序,必须等所有的前台线程运行完毕后才能退出;而后台线程的程序,只要前台的线程都终止了,那么后台的线程就会自动结束并推出程序。

一般前台线程用于需要长时间等待的任务,比如监听客户端的请求;后台线程一般用于处理时间较短的任务,比如处理客户端发过来的请求信息。

Performance_Schema.threads

每一个服务器端进程在该表中都有一行,表明是否启用监控和历史事件日志

mysql> SELECT * FROM threads\G
*************************** 1. row ***************************
THREAD_ID: 1
NAME: thread/sql/main
TYPE: BACKGROUND
PROCESSLIST_ID: NULL
PROCESSLIST_USER: NULL
PROCESSLIST_HOST: NULL
PROCESSLIST_DB: NULL
PROCESSLIST_COMMAND: NULL
PROCESSLIST_TIME: 80284
PROCESSLIST_STATE: NULL
PROCESSLIST_INFO: NULL
PARENT_THREAD_ID: NULL
ROLE: NULL
INSTRUMENTED: YES
HISTORY: YES
CONNECTION_TYPE: NULL
THREAD_OS_ID: 489803
...
*************************** 4. row ***************************
THREAD_ID: 51
NAME: thread/sql/one_connection
TYPE: FOREGROUND
PROCESSLIST_ID: 34
PROCESSLIST_USER: isabella
PROCESSLIST_HOST: localhost
PROCESSLIST_DB: performance_schema
PROCESSLIST_COMMAND: Query
PROCESSLIST_TIME: 0
PROCESSLIST_STATE: Sending data
PROCESSLIST_INFO: SELECT * FROM threads
PARENT_THREAD_ID: 1
ROLE: NULL
INSTRUMENTED: YES
HISTORY: YES
CONNECTION_TYPE: SSL/TLS
THREAD_OS_ID: 755399
...

当Performance Schema库初始化时,会将已经存在的线程填充到threads表中。从那之后,每当服务器新创建一个线程,就对应得在threads表中新增加一行。

在新创建的线程中,INSTRUMENTED和HISTORY列的值由setup_actors表决定。

当线程结束时,在threads表中对应的行将被移除。

和INFORMATION_SCHEMA.PROCESSLIST与SHOW PROCESSLIST的区别:

  • threads表不需要锁资源,对服务器性能有最小的影响。相反,INFORMATION_SCHEMA.PROCESSLIST与SHOW PROCESSLIST对服务器性能有着负面的影响因为他们需要锁资源。
  • threads表提供的信息更加全面。
  • 监控是可控制的(可以被关闭)
  • INFORMATION_SCHEMA.PROCESSLIST与SHOW PROCESSLIST需要用户有PROCESS权限,threads表只需要用户有SELECT权限

重要的字段:

  • PROCESSLIST_ID:PROCESSLIST_ID 与INFORMATION_SCHEMA.PROCESSLIST的ID值、SHOW PROCESSLIST的ID值相同、select connection_id()返回值相同

  • INSTRUMENTED:被线程执行的事件是否被MySQL监控(Whether events executed by the thread are instrumented,不知道理解的对不对。。。),值为YES或者NO

    • 对于前台线程,INSTRUMENTED 的初始值是由setup_actors中匹配的行决定的,匹配是根据 PROCESSLIST_USER和PROCESSLIST_HOST的值匹配的。
    • 对于后台线程,INSTRUMENTED的默认值是YES。setup_actors对此值没有影响,因为后台线程没有相对应得用户。
    • 对于任何线程,INSTRUMENTED的值都是可以在线程的生命周期内更改的。

    当被监控的事件执行时,一定会有如下的事实:

    • setup_consumers 对应的值是YES
    • threads.INSTRUMENTED的值是YES
    • setup_instruments对应的值是YES
  • History:与INSTRUMENTED类似

其余字段的值看参考资料吧。

参考资料:http://dev.mysql.com/doc/refman/5.7/en/threads-table.html

Performance_Schema.setup_instruments

setup_instruments存储着一系列监控器对象,代表着什么事件会被收集。(The setup_instruments table lists classes of instrumented objects for which events can be collected)

mysql> SELECT * FROM setup_instruments;
+------------------------------------------------------------+---------+-------+
| NAME | ENABLED | TIMED |
+------------------------------------------------------------+---------+-------+
...
| wait/synch/mutex/sql/LOCK_global_read_lock | YES | YES |
| wait/synch/mutex/sql/LOCK_global_system_variables | YES | YES |
| wait/synch/mutex/sql/LOCK_lock_db | YES | YES |
| wait/synch/mutex/sql/LOCK_manager | YES | YES |
...
| wait/synch/rwlock/sql/LOCK_grant | YES | YES |
| wait/synch/rwlock/sql/LOGGER::LOCK_logger | YES | YES |
| wait/synch/rwlock/sql/LOCK_sys_init_connect | YES | YES |
| wait/synch/rwlock/sql/LOCK_sys_init_slave | YES | YES |
...
| wait/io/file/sql/binlog | YES | YES |
| wait/io/file/sql/binlog_index | YES | YES |
| wait/io/file/sql/casetest | YES | YES |
| wait/io/file/sql/dbopt | YES | YES |
...

每一个在源码中的监控器都会在表中有一行,即使该监控器代码没有被执行。当一个监控器代码被启用并且执行,就会创造一个监控器实例,在 *_instances表中可见。

参考资料:http://dev.mysql.com/doc/refman/5.7/en/setup-instruments-table.html

Performance_Schema.setup_consumers

setup_consumers表用于配置事件的消费者类型,即收集的事件最终会写入到哪些统计表中。(The setup_consumers table lists the types of consumers for which event information can be stored and which are enabled)

mysql> SELECT * FROM setup_consumers;
+----------------------------------+---------+
| NAME | ENABLED |
+----------------------------------+---------+
| events_stages_current | NO |
| events_stages_history | NO |
| events_stages_history_long | NO |
| events_statements_current | YES |
| events_statements_history | YES |
| events_statements_history_long | NO |
| events_transactions_current | NO |
| events_transactions_history | NO |
| events_transactions_history_long | NO |
| events_waits_current | NO |
| events_waits_history | NO |
| events_waits_history_long | NO |
| global_instrumentation | YES |
| thread_instrumentation | YES |
| statements_digest | YES |
+----------------------------------+---------+

参考资料:http://dev.mysql.com/doc/refman/5.7/en/setup-consumers-table.html

http://www.cnblogs.com/cchust/p/5022148.html

Performance_Schema.setup_actors

setup_actors表决定着是否为前台进程(和客户端连接有关的进程)开启监控和历史事件日志。最多有100记录,可以通过修改performance_schema_setup_actors_size系统变量最大值。

mysql> SELECT * FROM setup_actors;
+------+------+------+---------+---------+
| HOST | USER | ROLE | ENABLED | HISTORY |
+------+------+------+---------+---------+
| % | % | % | YES | YES |
+------+------+------+---------+---------+

对于每一个前台进程,会根据用户名和主机名在setup_actors表中进行匹配。如果匹配成功,ENABLED和HISTORY列的值就会被分别赋给threads表中的INSTRUMENTED和HISTORY列。这能够让用户启用监控器和历史事件日志。如果没有在setup_actors表中匹配到,ENABLED和HISTORY列的值会被赋值为NO。

对于setup_actors表的改变不会影响现有的线程,只会改变现有线程创建的子线程。如果想要改变现有的线程,改变threads表中对应行的 INSTRUMENTED和HISTORY的值。

参考资料:http://dev.mysql.com/doc/refman/5.7/en/setup-actors-table.html

Performance_Schema.events_statements_history_long

Performance Schema Instrument Naming Conventions

http://dev.mysql.com/doc/refman/5.7/en/performance-schema-instrument-naming.html

Query Profiling Using Performance Schema

如下例子示例了如何像SHOW PROFILES和SHOW PROFILE一样分析数据。

1.默认的,MySQL允许所有前台线程监控和收集历史事件。

mysql> SELECT * FROM setup_actors;
+------+------+------+---------+---------+
| HOST | USER | ROLE | ENABLED | HISTORY |
+------+------+------+---------+---------+
| % | % | % | YES | YES |
+------+------+------+---------+---------+

可以做如下改变:

mysql> UPDATE performance_schema.setup_actors SET ENABLED = 'NO', HISTORY = 'NO'
-> WHERE HOST = '%' AND USER = '%'; mysql> INSERT INTO performance_schema.setup_actors (HOST,USER,ROLE,ENABLED,HISTORY)
-> VALUES('localhost','test_user','%','YES','YES');
mysql> SELECT * FROM performance_schema.setup_actors;
+-----------+-----------+------+---------+---------+
| HOST | USER | ROLE | ENABLED | HISTORY |
+-----------+-----------+------+---------+---------+
| % | % | % | NO | NO |
| localhost | test_user | % | YES | YES |
+-----------+-----------+------+---------+---------+

2.确保statement and stage监控器在setup_instruments表中启用。

mysql> UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES'
-> WHERE NAME LIKE '%statement/%'; mysql> UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES'
-> WHERE NAME LIKE '%stage/%';

3.确保events_statements_* 和events_stages_*启用。

mysql> UPDATE performance_schema.setup_consumers SET ENABLED = 'YES'
-> WHERE NAME LIKE '%events_statements_%'; mysql> UPDATE performance_schema.setup_consumers SET ENABLED = 'YES'
-> WHERE NAME LIKE '%events_stages_%';

4.运行想要分析的语句:

mysql> SELECT * FROM employees.employees WHERE emp_no = 10001;
+--------+------------+------------+-----------+--------+------------+
| emp_no | birth_date | first_name | last_name | gender | hire_date |
+--------+------------+------------+-----------+--------+------------+
| 10001 | 1953-09-02 | Georgi | Facello | M | 1986-06-26 |
+--------+------------+------------+-----------+--------+------------+

5.通过events_statements_history_long表确定EVENT_ID

mysql> SELECT EVENT_ID, TRUNCATE(TIMER_WAIT/1000000000000,6) as Duration, SQL_TEXT
-> FROM performance_schema.events_statements_history_long WHERE SQL_TEXT like '%10001%';
+----------+----------+--------------------------------------------------------+
| event_id | duration | sql_text |
+----------+----------+--------------------------------------------------------+
| 31 | 0.028310 | SELECT * FROM employees.employees WHERE emp_no = 10001 |
+----------+----------+--------------------------------------------------------+

6.一个语句很可能会触发很多事件,这些事件都是循环嵌套的,每个阶段的事件记录有一个nesting_event_id列,包含父表的event_id。(Query the events_stages_history_long table to retrieve the statement's stage events. Stages are linked to statements using event nesting. Each stage event record has a NESTING_EVENT_ID column that contains the EVENT_ID of the parent statement.

求翻译,MLGB)

mysql> SELECT event_name AS Stage, TRUNCATE(TIMER_WAIT/1000000000000,6) AS Duration
-> FROM performance_schema.events_stages_history_long WHERE NESTING_EVENT_ID=31;
+--------------------------------+----------+
| Stage | Duration |
+--------------------------------+----------+
| stage/sql/starting | 0.000080 |
| stage/sql/checking permissions | 0.000005 |
| stage/sql/Opening tables | 0.027759 |
| stage/sql/init | 0.000052 |
| stage/sql/System lock | 0.000009 |
| stage/sql/optimizing | 0.000006 |
| stage/sql/statistics | 0.000082 |
| stage/sql/preparing | 0.000008 |
| stage/sql/executing | 0.000000 |
| stage/sql/Sending data | 0.000017 |
| stage/sql/end | 0.000001 |
| stage/sql/query end | 0.000004 |
| stage/sql/closing tables | 0.000006 |
| stage/sql/freeing items | 0.000272 |
| stage/sql/cleaning up | 0.000001 |
+--------------------------------+----------+
15 rows in set (0.00 sec)

参考资料:http://dev.mysql.com/doc/refman/5.7/en/performance-schema-query-profiling.html

MySQL命令行参数

http://blog.51yip.com/mysql/1056.html

key_len长度计算方法

变长字段需要额外的2个字节,固定长度字段不需要额外的字节。而null都需要1个字节的额外空间,所以以前有个说法:索引字段最好不要为NULL,因为NULL让统计更加复杂,并且需要额外的存储空间。这个结论在此得到了证实。

key_len的长度计算公式:

varchr(10)变长字段且允许NULL:10 * (Character Set:utf8=3,gbk=2,latin1=1) + 1(NULL) + 2(变长字段)

varchr(10)变长字段且不允许NULL:10 * (Character Set:utf8=3,gbk=2,latin1=1) + 2(变长字段)

char(10)固定字段且允许NULL:10 * (Character Set:utf8=3,gbk=2,latin1=1) + 1(NULL)

char(10)固定字段且允许NULL:10 * (Character Set:utf8=3,gbk=2,latin1=1)

参考资料:http://www.ittang.com/2014/0612/13360.html

参数使用说明

http://dev.mysql.com/doc/refman/5.7/en/dynindex-sysvar.html

http://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html

MySQL的语句执行顺序



http://www.cnblogs.com/rollenholt/p/3776923.html

varbinary vs varchar

http://blog.csdn.net/sxingming/article/details/52628531

http://blog.itpub.net/7728585/viewspace-2132521

http://blog.sina.com.cn/s/blog_4de07d5e01010jc4.html

MySQL 使用经验的更多相关文章

  1. mysql使用经验总结

    在工作中难免会遇到一些这个问题那个问题,当然在mysql中也不例外.今天就让我们来学学mysql中一些比较常用的东西  . 1.有时我们想去查某张表中的字段,但是表中的数据多,字段也很多,如果用sel ...

  2. Java工程师必备书单

    微信公众号[程序员江湖] 作者黄小斜,斜杠青年,某985硕士,阿里 Java 研发工程师,于 2018 年秋招拿到 BAT 头条.网易.滴滴等 8 个大厂 offer,目前致力于分享这几年的学习经验. ...

  3. 【转】Java工程师必备书单

    江湖路险,你我同行. Java开发工程师一般负责后端开发,当然也有专门做Java Web的工程师,但是随着前后端的分离,越来越多的Java工程师需要往大后端方向发展. 今天我们就来介绍一下Java后端 ...

  4. java后端书单

    Java开发工程师一般负责后端开发,当然也有专门做Java Web的工程师,但是随着前后端的分离,越来越多的Java工程师需要往大后端方向发展. 今天我们就来介绍一下Java后端开发者的书单. 首先要 ...

  5. Java后端工程师必备书单(从Java基础到分布式)

    Java开发工程师一般负责后端开发,当然也有专门做Java Web的工程师,但是随着前后端的分离,越来越多的Java工程师需要往大后端方向发展. 今天我们就来介绍一下Java后端开发者的书单. 首先要 ...

  6. 为什么你精通CRUD,却搞不懂数据库的基本原理?

    原创声明 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 本文思维导图

  7. Mysql数据库的使用经验总结

    1. 对mysql插入中文的时候显示乱码,搞了很多天,把服务端.客户端和数据库的编码全改为u8了又重新创建数据库和表还是不行,到最后却发现没有乱码!原来只是windows的cmd没有支持u8,换个客户 ...

  8. mysql 常用,使用经验

    mysql default  boolean字段 `enable` char(1) NOT NULL DEFAULT '1' COMMENT '启(禁)用',结果: this.enable ? &qu ...

  9. Asp.net Core 通过 Ef Core 访问、管理Mysql

    本文地址:http://www.cnblogs.com/likeli/p/5910524.html 环境 dotnet Core版本:1.0.0-preview2-003131 本文分为Window环 ...

随机推荐

  1. NullSafe基于Runtime的深度解析

    Objective-C是一门动态语言,一个函数是由一个selector(SEL),和一个implement(IML)组成的. 执行一个方法时如果系统找不到方法会给几次机会寻找方法,实在没有此方法就会抛 ...

  2. 在JQuery中如何获取当前时间?

    ////发表时间(now) function p(s) { return s < 10 ? '0' + s : s; } var myDate = new Date(); //获取当前年 var ...

  3. C语言之浮点数

    #include<stdio.h> int main(){printf("请分别输入身高的英尺和英寸," "如输入\"5 7\"表示5英尺 ...

  4. 边框(Border) 和 轮廓(Outline) 属性

    border 复合属性.设置对象边框的特性. 标签定义及使用说明 如果上述值缺少一个没有关系,例如border:#FF0000;是允许的. 默认值: not specified 继承: no Java ...

  5. 问题记录-运行Tomcat,项目程序没有响应

    问题描述:运行Tomcat,项目程序没有响应原因在于 修改成一致路径即可解决.

  6. MySQL管理员珍藏:十大必备工具盘点

    作者:dongdongzzcs 第1页: [IT168 专稿]本文的作者Daniel Nichter是MySQL工具的开发者,他为MySQL管理员推荐了十款必备工具.以下是全文内容: MySQL是一套 ...

  7. SQL Server Profiler追踪数据库死锁

  8. 【JSOI2008】最大数

    https://www.luogu.org/problem/show?pid=1198 之前刚学完Splay想找题练手的时候做的,写完Splay交上去了才发现这应该是线段树裸题23333 Splay解 ...

  9. UVA 12009 - Avaricious Maryanna(数论)

    UVA 12009 - Avaricious Maryanna 题目链接 题意:给定一个n.求出n个数位组成的数字x,x^2的前面|x|位为x 思路:自己先暴力打了前几组数据,发现除了1中有0和1以外 ...

  10. centos 6.5 安装mongodb2.6

    前言: 系统版本号:Centos-6.5-x86_64 *** Centos编译安装mongodb 2.6 系统最好是64位的,才干更好发挥mongodb的性能 1.准备,下载源文件(二进制编译版) ...