我有一个主MySQL服务器和一个从服务器。数据在它们之间复制。
当我在主人身上运行此查询时,需要花费数小时;在奴隶上需要几秒钟。 EXPLAIN计划重新计算 - 奴隶检查的行数远远少于主人。
但是,由于这两个数据库中的结构和数据完全相同(或者至少应该是这样),并且它们都运行相同版本的MySQL(5.5.31 Enterprise),所以我不会&#39了解造成这种情况的原因。
这是与this question(和其他人)类似的症状,但我不认为它是相同的根本原因,因为我的两台服务器通过MySQL复制同步,结构和数据内容是(或应该是)相同的,OS&两台服务器上的硬件资源完全相同 - 它们是VMWare,另一台是另一台服务器的映像。
我已经验证了两个服务器上每个表中的行数完全相同,并且它们的配置是相同的(除了具有指向主服务器的指令的从服务器)。如果没有通过数据本身来查看是否存在任何差异,我不确定我还能检查什么,并且会对任何建议表示感谢。
查询
SELECT COUNT(DISTINCT(cds.company_id))
FROM jobsmanager.companies c
, jobsmanager.company_jobsmanager_settings cjs
, jobsmanager.company_details_snapshot cds
, vacancies v
WHERE c.company_id = cjs.company_id
AND cds.company_id = c.company_id
AND cds.company_id = v.jobsmanager_company_id
AND cjs.is_post_a_job = 'Y'
AND cjs.can_access_jobsmanager = 'Y'
AND cjs.account_status != 'suspended'
AND v.last_live BETWEEN cds.record_date - INTERVAL 365 DAY AND cds.record_date
AND cds.record_date BETWEEN '2016-01-30' AND '2016-02-05';
大师解释如下,驾驶台上300万行,没有按键使用,并且需要一个多小时才能返回结果:
+----+-------------+-------+--------+-------------------------+----------------+---------+---------------------------------+---------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+-------------------------+----------------+---------+---------------------------------+---------+--------------------------+
| 1 | SIMPLE | v | ALL | job_owner,last_live_idx | NULL | NULL | NULL | 3465433 | |
| 1 | SIMPLE | c | eq_ref | PRIMARY | PRIMARY | 4 | s1jobs.v.jobsmanager_company_id | 1 | Using where; Using index |
| 1 | SIMPLE | cds | ref | PRIMARY,company_id_idx | company_id_idx | 4 | jobsmanager.c.company_id | 538 | Using where |
| 1 | SIMPLE | cjs | eq_ref | PRIMARY,qidx,qidx2 | PRIMARY | 4 | jobsmanager.c.company_id | 1 | Using where |
+----+-------------+-------+--------+-------------------------+----------------+---------+---------------------------------+---------+--------------------------+
奴隶使用不同的驱动表,使用索引,预测更多像检查的310,000行,并在几秒钟内返回结果:
+----+-------------+-------+--------+-------------------------+-----------+---------+----------------------------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+-------------------------+-----------+---------+----------------------------+--------+--------------------------+
| 1 | SIMPLE | cds | range | PRIMARY,company_id_idx | PRIMARY | 3 | NULL | 310381 | Using where; Using index |
| 1 | SIMPLE | c | eq_ref | PRIMARY | PRIMARY | 4 | jobsmanager.cds.company_id | 1 | Using index |
| 1 | SIMPLE | cjs | eq_ref | PRIMARY,qidx,qidx2 | PRIMARY | 4 | jobsmanager.c.company_id | 1 | Using where |
| 1 | SIMPLE | v | ref | job_owner,last_live_idx | job_owner | 2 | jobsmanager.cds.company_id | 32 | Using where |
+----+-------------+-------+--------+-------------------------+-----------+---------+----------------------------+--------+--------------------------+
我在两台服务器上都运行了ANALYZE TABLE,OPTIMIZE TABLE和REPAIR TABLE ... QUICK,试图让它们保持一致,没有运气。
作为临时解决方案,我可以在奴隶上运行查询,因为他们在cron脚本中,即使他们在奴隶上花了很长时间,他们也不会像他们那样增加主人的负担当他们在主人身上跑时但是,我很感激任何其他信息,说明为什么这些不同或我还能检查/修改哪些可以解释两者之间如此巨大的差异。我唯一能找到的是奴隶有更多的免费内存,因为它很少使用;那个人会解释这个吗?如果不是其他什么?
$ ssh s1-mysql-01 free # master
total used free shared buffers cached
Mem: 99018464 98204624 813840 0 160752 55060632
-/+ buffers/cache: 42983240 56035224
Swap: 4095992 4095992 0
$ ssh s1-mysql-02 free # slave
total used free shared buffers cached
Mem: 99018464 80866420 18152044 0 224772 72575168
-/+ buffers/cache: 8066480 90951984
Swap: 4095992 206056 3889936
$
非常感谢。
答案 0 :(得分:1)
2解释的唯一真正的巨大差异是,在主人的空缺表上没有使用索引。
您可以尝试将index hint(强制索引)放入主数据库中以强制使用job_owner索引。
您还可以尝试在master上的上述查询中涉及的所有表上运行analyze table,以确保更新表和索引统计信息。