84个MySQL性能优化的首选技巧

1、添加索引
2、去掉不必要的索引
3、使用 benchmarking 做基准测试

4、只获取你需要的信息,减少流量:
a) 使用 limit 对数据进行分页
b) 不要使用 SELECT *
c) 不要使用多个小查询,如果能组合成一个长查询,会更加高效

5、使用 EXPLAIN 来查看 SQL 执行效果
6、使用 Slow Query Log (应该总是开启它)
7、如果使用了 GROUP BY,就不要使用 DISTINCT

8、正确地对数据进行分区
以集群为例,不要等到你需要集群是才开始考虑集群

9、考虑 INSERT 的性能
a) 批量 INSERT 和 UPDATE
b) 使用 LOAD DATA 替代 INSERT

10、LIMIT m,n 并不像传说中那样快
11、如果超过 2000 条数据,不要使用 ORDER BY RAND()
12、SELECT 经常更新的数据或大数据集是,使用 SQL_NO_CACHE
13、LIKE 查询的开头部分避免使用通配符
14、避免使用关联子查询和 IN SELECT 和 WHERE 子句 (尽量避免 IN)
15、配置参数 --
16、不要比较运算出来的字段 - 隔离索引列
17、innodb_flush_commit=0 能避免数据库集群的 slave 延迟
18、ORDER BY 和 LIMIT 与相等的和覆盖的索引一起使用时,效果最佳
19、错开工作负荷,不要让管理员的工作影响到用户访问速度
20、使用乐观锁,而不是悲观锁。试着使用共享锁,定而不是独占锁。比较共享模式和 FOR UPDATE
21、对于联机事务处理(OLTP),尽量使用行锁定,而不是表锁定。

22、了解存储引擎以及哪种引擎最符合你的需求,了解这些引擎之间的不同。
使用MERGE表和ARCHIVE表记录日志。

23、优化数据类型,使数据类型保持一致。使用 PROCEDURE ANALYSE() 来决定是否只需要更小的数据类型。
24、把 text/blobs 类型的数据从元数据中分离出来。如果你不需要 text/blobs 类型的数据,不要把它们放入结果集中。
25、尽量压缩 text/blobs 类型的数据
26、压缩静态数据
27、不要经常备份静态数据
28、衍生表(FROM子句中的子查询)对于检索无须排序的 BLOBs 非常实用(当第一部分查找到IDs,使用该ID获取其他数据时,自连接(self-join)能加快查询速速)。
29、尽量开启并增加查询缓存(query cache)以及缓冲缓存(buffer cache)。
30、ALTER TABLE…ORDER BY 可以按时间顺序获取数据,并且用另一个字段重新排序结果数据。
31、InnoDB 总是将主键作为所有索引的一部分,所以尽量保持主键精简,小心索引中出现多余的字段。
32、不要复制索引。
33、在主/从服务器中使用不同的存储引擎,除非需要在表里进行全文索引。
34、BLACKHOLE 引擎以及复制在记录日志等情况下比 FEDERATED 表快。
35、设计健全的查询模式,不要害怕表联合(JOINs),通常它们比非范式化更快。
36、不要使用布尔型标识。
37、使用适当的键和 ORDER BY 来替代 MAX。
38、尽量保持数据库服务器干净,没必要在上面安装窗口系统。
39、充分利用操作系统的强大功能。
40、雇用一个 MySQL 认证的 DBA。
41、这里有许多咨询公司和 MySQL 的专业服务能帮助你。

42、配置变量和技巧
a、从MySQL自带的配置文件中,选择一个使用
b、key_buffer, unix cache (保留一些内存), per-connection 变量, innodb memory 变量
c、注意 global 以及 per-connection 变量
d、检查 SHOW STATUS 和 SHOW VARIABLES (5.0 以上版本还提供了 GLOBAL | SESSION)
e、小心系统使用过多的交换内存。在 Linux 系统里,尽量做到“无交换”(避免操作系统对 innodb 数据文件进行 filecache,尽量设置 innodb_flush_method=O_DIRECT(根据不同操作系统而定))
f、整理表碎片,重建索引,维护表。
g、如果设置 innodb_flush_txn_commit=1,使用有后备电源的硬件缓存写保护(write controller)
h、更多的内存有助于提升磁盘速度。
i、使用64位架构。

43、知道何时拆分复杂的查询,以及何时合并小的查询。
44、调试(Debugging)为下,测试(testing)为上。
45、尽量一次删除较少的数据。
46、通过 ARCHIVE 表和 MERGE 表将旧数据归档。
47、使用 INET_ATON 和 INET_NTOA 保存 ip 地址,而不是 CHAR 或 VARCHAR。
48、养成把 email 地址 REVERSE() 的习惯,这样能方便地查找域名。
49、--skip-name-resolve
50、增加 myisam_sort_buffer_size 的值可以优化大量数据插入(这是一个 per-connection 变量)。
51、为插入时缓存找到内存调整参数。
52、对于数据仓库,需要增加临时表大小(缺省为 32Mb),这样就不会被写到磁盘(同时也受到 max_heap_table_size 的限制,缺省为 16Mb)
53、首先要符合范式,适当的地方非范式。
54、数据库不是电子表格,尽管电子表格有点像 Access。不过,Access 不是真正的数据库。
55、在 5.1 版本中,BOOL/BIT NOT NULL 类型是 1 bit,在以前的版本中是 1 byte。
56、NULL 数据类型会比 NOT NULL 类型占用更多的存储空间。
57、选择合适的字符集,UTF16 每个字符要占用两字节,不管是否需要,latin1 比 UTF8 更快。
58、使类似的查询保持一致性,便于使缓存得到利用。
59、保持良好的 SQL 查询标准。
60、不要使用不推荐的功能。
61、合理使用触发器。
62、以 SQL_MODE=STRICT 方式运行,将有助于获得警告信息。
63、Turning OR on multiple index fields (<5.0) into UNION may speed things up (with LIMIT), after 5.0 the index_merge should pick stuff up.
64、/tmp 目录放到有后备电源和写缓存的设备上。
65、对 innodb 日志文件有后备电源的 RAM。
66、use min_rows and max_rows to specify approximate data size so space can be pre-allocated and reference points can be calculated.
67、as your data grows, indexing may change (cardinality and selectivity change). Structuring may want to change. Make your schema as modular as your code. Make your code able to scale. Plan and embrace change, and get developers to do the same.
68、pare down cron scripts
69、create a test environment
70、try out a few schemas and storage engines in your test environment before picking one.
71、Use HASH indexing for indexing across columns with similar data prefixes
72、Use myisam_pack_keys for int data
73、Don’t use COUNT * on Innodb tables for every search, do it a few times and/or summary tables, or if you need it for the total # of rows, use SQL_CALC_FOUND_ROWS and SELECT FOUND_ROWS()
74、use --safe-updates for client
75、Redundant data is redundant
76、Use INSERT … ON DUPLICATE KEY update (INSERT IGNORE) to avoid having to SELECT
77、use groupwise maximum instead of subqueries
78、be able to change your schema without ruining functionality of your code
79、source control schema and config files
80、for LVM innodb backups, restore to a different instance of MySQL so Innodb can roll forward
81、use multi_query if appropriate to reduce round-trips
82、partition appropriately
83、partition your database when you have real data
84、segregate tables/databases that benefit from different configuration variables

本文由何键译自Top 84 MySQL Performance Tips

还未译完,会在近期抽空补齐。

1天之前

 

上一篇:leetcode 84. 柱状图中最大的矩形


下一篇:面试题-Java中级篇(12)