我正在使用 mysqldump 对完全由 InnoDB 表组成的架构执行定期备份。mysqldump 文档有这样的说法--single-transaction
:
--single-transaction 选项和 --lock-tables 选项是互斥的,因为 LOCK TABLES 会导致隐式提交任何挂起的事务。
然而,这里(以及堆栈交换网络上的其他地方)大约有无数篇博客文章和答案推荐:
mysqldump --single-transaction --skip-lock-tables my_database > my_database.sql
Run Code Online (Sandbox Code Playgroud)
如果这两个选项是互斥的,我认为指定--single-transaction
就足够了。然而,文档还说明了这一点--opt
:
该选项默认启用,是 --add-drop-table --add-locks --create-options --disable-keys --extended-insert --lock-tables --quick -- 组合的简写设置字符集。
这让我相信--lock-tables
默认情况下是打开的。
我是否需要指定--skip-lock-tables
或--single-transaction
仅设置后者足以确保表在转储期间不被锁定?
我一次又一次地注意到,当我EXPLAIN
用GROUP BY
子句查询时,我得到filesort
了一个额外的条件。很久以前我读过一个建议,GROUP BY NULL
在这些情况下使用以避免文件排序,它确实消除了那种令人讨厌的filesort
情况。
我认为,如果不存在ORDER BY
子句,则 dbms 将只提供任意顺序或最有效的任何顺序,而不是按某些需要文件排序的神秘列进行排序。对我来说,我需要包含一个额外的指示,这基本上相当于说“不要做任何愚蠢的事情”,这似乎很奇怪。
我的问题是为什么这甚至是必要的,并且ORDER BY NULL
实际上增加了性能?
假设我有一个类似的查询:
SELECT *
FROM table_a
JOIN table_b USING (id)
WHERE table_b.column = 1
Run Code Online (Sandbox Code Playgroud)
我有一个索引id
和一个索引,column
但我经常添加一个复合索引,两者都可以提高这样的查询效率。我的问题是关于索引中列的顺序。通过反复试验,我发现有时 DBMS 更喜欢连接索引,有时它更喜欢WHERE
索引。
在上面的查询中,是否有一个硬性、快速的规则可以让我知道哪个键顺序最有效?
通常我只添加两个索引,运行EXPLAIN
查询并检查哪个是首选的,然后删除另一个。但是这个过程感觉可以通过更好地理解确定索引顺序所涉及的逻辑来改进。
更新(tl;博士;):
我在这里提交了一个错误报告:https : //bugs.mysql.com/bug.php?id=99593已被确认并提供了解决方法。有关详细信息,请参阅下面的答案。
某些查询似乎在 MySQL 8.0.20 下挣扎,我想知道是否有人可以指出一些可能的解决方案。目前我已经启动并运行了旧服务器,仍在 5.7.30 上运行,因此很容易对性能结果进行 A/B。两台服务器都有 32GB 的 RAM,几乎相同的配置,所有表都是 InnoDB。以下是一些(相关)设置:
innodb_flush_log_at_trx_commit = 0
innodb_flush_method = O_DIRECT
innodb_file_per_table = 1
innodb_buffer_pool_instances = 12
innodb_buffer_pool_size = 16G
innodb_log_buffer_size = 256M
innodb_log_file_size = 1536M
innodb_read_io_threads = 64
innodb_write_io_threads = 64
innodb_io_capacity = 5000
innodb_thread_concurrency = 0
Run Code Online (Sandbox Code Playgroud)
SELECT DISTINCT vehicle_id, submodel_id, store_id
FROM product_to_store pts
JOIN product_to_vehicle ptv USING (product_id)
WHERE vehicle_id != 0 AND pts.store_id = 21;
Run Code Online (Sandbox Code Playgroud)
此查询产生以下解释:
MySQL 8.0.20(查询需要 24 秒):
+----+-------------+-------+------------+------+-------------------------------------------+--------------------------+---------+----------------+--------+----------+------------------------------+ …
Run Code Online (Sandbox Code Playgroud) mysql ×3
group-by ×1
index-tuning ×1
innodb ×1
mysql-5.7 ×1
mysql-8.0 ×1
mysqldump ×1
optimization ×1
order-by ×1