我运行测试服务器和生产服务器..
当我对测试服务器上的数据库结构进行一些更改时,我会保存所有 SQL 查询,以便稍后在部署更新时在生产服务器上运行它们
今天我在生产服务器上部署了一些更新,但至少有一个查询现在太慢以至于会超时(需要几分钟)。过去需要 1-2 秒
在测试服务器上,相同的查询仍然像以前一样顺利运行
询问
SELECT dv.id,dv.client_id,b.name block_name,dv.is_ocr_pending,dv.time,dv.label,dv.is_pdf_broken,dv.is_pdf_scan,dv.is_pic,dv.file_sha1,dv.file_ext,dv.file_ext_thumb,dv.file_size,dv.file_size_original,dv.num_pages,dv.dpi,dv.ocr_confidence,dv.ocr_recall_id,dv.ocr_vatno,cv.name ocr_vatno_name,dv.ocr_vatno_country,dv.ocr_is_vatno_verified,dv.ocr_invoice_id_,dv.ocr_invoice_time,dv.ocr_invoice_time_due,dv.ocr_fi_type,dv.ocr_fi_payment_id_,dv.ocr_is_fi_payment_verified,dv.ocr_fi_creditorno,dv.ocr_bank_code,dv.ocr_bank_code_id,dv.ocr_is_bank_code_verified,dv.ocr_bank_account,dv.ocr_is_bank_account_verified,dv.ocr_bank_iban,dv.ocr_is_bank_iban_verified,dv.ocr_bank_swift,dv.ocr_bank_swift_id,dv.ocr_is_bank_swift_verified,dv.ocr_products_pattern,dv.ocr_total,dv.ocr_is_total_verified,dv.ocr_vat,dv.ocr_currency
FROM `data_voucher` dv
LEFT JOIN `block` b ON b.id=dv.block_id
LEFT JOIN `cache_vatno` cv ON cv.vatno=dv.ocr_vatno
ORDER BY dv.time DESC,dv.id DESC
LIMIT 0,25
它在一台服务器上超时但在另一台服务器上没有超时是没有意义的。当我转储表结构时,查询影响转储是否完全相同?
如果我排除行LEFT JOIN cache_vatno cv ON cv.vatno=dv.ocr_vatno
并从 select 子句中删除该字段cv.name ocr_vatno_name
,它将像部署之前一样运行和完成
我不知道该怎么办?
我现在已经使用 perconas extrabackup 转储生产数据库并将其部署在测试服务器上。现在测试服务器有同样的问题?
我可以cache_vatno
毫无问题地浏览 phpmyadmin中的表格
该表data_voucher
有超过 100k 行
已尝试重启mysql
添加EXPLAIN
到查询中给出这个
慢10倍?如果你再次运行它,它会恢复正常吗?
那是正常的。在 big 之前
ALTER
,该查询的所有数据都缓存在 RAM 中。然后把ALTER
大部分都撞掉了。之后,查询必须转到磁盘,因此速度慢了 10 倍。再次运行应该会在缓存中看到它并且再次变快。如果这与您所看到的不符,请提供以下内容,以便我们深入挖掘:
SHOW CREATE TABLE
每张桌子innodb_buffer_pool_size
请注意,查询必须从所有 3 个表中读取所有行,并将所有数据放入临时表中进行排序。
好像不需要
LEFT
,能去掉吗?可能的索引(待查看上述信息):
如果连接是 1:1?假设他们是,试试这个重写:
理由:我将 JOIN 转换为子查询,从而使事情变得显而易见,事情是 1:1,并让优化器只关注一个表 (
dv
)。这应该允许它INDEX(time, id)
同时处理ORDER BY
和LIMIT
,从而在 25 行后停止。不幸的是,这仍然留下了
SQL_CALC_FOUND_ROWS
. 它必须继续计算该索引中的其余行。因此,删除 CALC可能会显着加快查询速度。用户界面真的需要它吗?...