为什么更改为另一个主键索引会降低此查询的性能?

时间:2012-04-24 04:16:17

标签: mysql

我有这个查询,工作正常。

SELECT SUM(amount) FROM company.invoice_line WHERE item_id != shipping 
    AND item_id != '' 
    AND invoice_id IN 
        (SELECT id_invoices FROM company.invoices WHERE customer = 'XX' 
            AND sales_rep = 'XXX');

目的是总结来自客户的所有代表销售额。 客户 rep 数据相关并存储在invoice表格中,invoice line表格与invoice表格相关联。

对于我正在使用的数据大小,查询大约需要0.015秒

我更改了查询中的id_invoices,其中另一个PK是VARCHAR,但没有标记为唯一或不标记。

原因是事先,我有一个残酷的设计,其中invoice将被插入到数据库中,然后查询将立即询问invoice的自动递增的PK用作外键。

为了有效地使用BULK INSERT,我需要访问几乎所有数据的唯一标识符,而不依赖于自动递增的“vanilla”INT PK。我按照上面的说法完成了这项工作,并添加了可用作外键的其他列等等。

我的插入率现在很棒,但现在查询需要7秒以上

重申一下,我之前使用vanilla auto-increment int作为PK。将外键切换到VARCHAR会真的破坏性能吗?

我的下一步似乎是恢复到int id,但是不是允许MySQL在插入时自动增加,而是手动创建这些int索引,所以我仍然可以使用批量插入。从查询的角度来看,应该没关系......应该吗?

任何帮助都将不胜感激。

戴恩

1 个答案:

答案 0 :(得分:1)

好的,首先你需要使用EXPLAIN来确定查询计划中发生了什么,看看还有什么变化。

其次,VARCHAR列比INT列更慢匹配,但通常它只是一个常数增加(例如,它是k * O(n)vs O(n),其中k与n无关)。 ....如果两个表上的字符集不同,则除外。然后,当MySQL尝试匹配两个不同的字符集时,它就成了一个巨大的问题。谁知道为什么,这只是缓慢的mmkay。

第三,你的插页真的很慢,需要进行大规模的重新设计吗?从您的问题中不清楚您正在做什么,但很难看出随机插入的性能如何对您的工作负载产生巨大影响,您需要制作一个非标准的表结构,这使得其他所有工作都变得更难和更慢在它周围?

最后,关于批量插入的最后一个问题 - 如果你预先创建行,插入不会起作用(除非你用ON DUPLICATE KEY做某事)。但是我总是试着坚持使用int ID来做这种事情,除非有一个很好的理由不这样做。