mysql 杂记
mysql 优化
mysql 关键字执行顺序 以及 mysql 配置的影响(比如 join_buffer 对 join 的影响)
- from on join where group by (avg sum) having select distinct order by
mysql execution plan
- 待补充
《高性能 mysql》 中的 索引 和 查询优化 section
- 索引 section DONE
mysql 锁
- 和 mvcc 有关!
FAQ
-
为什么 mysql join 查询需要用小表驱动大表 ?
- mysql 的查询语句应该是一下子发到客户端,因为 优化器和 parser 是在服务端。如果查询语句不是一下子发送 server 端,mysql 的这些组件将无法工作
- 这个问题没有找到权威的答案,也没有做实验所需的数据。我觉得网上的那些 什么数据库训练链接 等解释是不对。 据目前缩查的资料而言,对简单的 2 个表 join, sql 优化器会作出正确的选择(基本如此)。对于复杂的 join, 我们需要保证上一步 join 产生的数据较小,join 操作路径是往每一步都是往最少的方向走,这样会减少后续的 数据库引擎操作,磁盘 IO。 最主要的就是为了减少回表 io
-
为什么 子查询 is bad
- 给出的佐证这个观点的例子: subquery 会被执行 n 次, 所以 subquery 不好。但是 subquery 真的是只是这样?
- 如果 subquery 无法避免,可以考虑拆分为多个短查询,然后在应用程序里面做处理
-
why MySQL exists is better than in ?
- However, the query optimizer now treats EXISTS and IN the same way, whenever it can, so you’re unlikely to see any significant performance difference. 所以只要保证 数据库的版本不能太老. 但是使用 exists 还是好的, in 在碰到 null 会有一些问题。如果能把逻辑放在应用层里面实现,就应该把逻辑放到应用层里面。
-
覆盖索引
- 就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。
- 满足以上条件的就是覆盖索引,可能是单个 key 的索引,也有可能是复合索引 (似乎之前就知道了,为什么今天又重新思考一下?)
- 不见得能建立一个简单的覆盖索引吧 (如何建立在单个字段上的索引,如 idx_created_at。 如果查询语句只查询 created_at。 那么 idx_created_at 就是一个覆盖索引。不需要回表通过聚簇索引重新查一次。覆盖索引更恰当的称呼是索引覆盖 )
- 其它相关的概念: 聚集索引, 辅助索引, 复合索引
-
索引的 基数选择问题
- 和数据量有关,和表结构无关。所以在写查询语句时,要相信 mysql 优化器,不要指定 hints, for index 之类的。
-
为什么禁用 query cache? 因为 query cache 对只读的表有提升效果,但是现实中的数据库应该是有读有写的
-
怎么看到 mysql 查询语句和 锁操作相关的
调优
- 配置上调优, 各种 buffer size 调整, socket 连接超时时间!
深刻话题
某些参数设置的原因,所以性能会有很高的提升
发散思维
- 有的语句要比另外语句好,可能是因为涉及到 锁 比较少吧