[英]MySQL query optimisation
我有一個數據庫表,用於存儲導入的信息。 為了簡單起見,它類似於:
CREATE TABLE `data_import` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`amount` DECIMAL(12,2) NULL DEFAULT NULL,
`payee` VARCHAR(50) NULL DEFAULT NULL,
`posted` TINYINT(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
INDEX `payee` (`payee`)
)
我還有一個存儲導入規則的表:
CREATE TABLE `import_rules` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`search` VARCHAR(50) NULL DEFAULT NULL,
PRIMARY KEY (`id`),
INDEX `search` (`search`)
)
想法是,對於每個導入的事務,查詢都需要嘗試查找單個匹配規則-此匹配是在data_import.payee和import_rules.seach字段上完成的。 因為這兩個都是varchar字段,所以已將它們編入索引,以期使查詢速度更快。
到目前為止,這是我提出的,似乎工作正常。 盡管比我希望的慢。
SELECT i.id, i.payee, i.amount, i.posted r.id, r.search
FROM import_data id
LEFT JOIN import_rules ir on REPLACE(i.payee, ' ', '') = REPLACE(ir.search, ' ', '')
上面的查詢無法滿足的一件事是,如果import_data.posted = 1,那么我不需要為該行找到規則-是否可以停止該特定行上的查詢聯接? 同樣,如果收款人為null,則也不應嘗試加入。
我還有其他方法可以對此進行優化嗎? 我意識到進行文本聯接不是理想的方法……不確定是否有更好的方法。
我強烈建議您做任何可以擺脫該JOIN
中的REPLACE
的事情。 在聯接的兩側使用REPLACE
完全消除了在任何一個表上使用索引的能力。
假設您可以擺脫REPLACE
(通過清除現有數據和/或新數據):
N
在VARCHAR(N)
小如,你可以,因為它會影響到指數的一側(或可以說,使用索引前綴)。 import_rules
上使search
索引UNIQUE
-那么您可以確定每行import_data
僅返回1行結果 您可以拋出AND
到您的WHERE
子句中,如果你想執行你“請不要在此情況下,加入”的規則。
LEFT JOIN import_rules ir ON id.payee=ir.search AND id.posted != 1
在聯接上使用REPLACE()可能會破壞索引,因為它具有字段中值的索引,而不是REPLACE()之后的修改值。
至於不加入,您已經在使用LEFT JOIN,因此不匹配的加入將對import_rules字段產生NULL。 您應該能夠添加WHERE子句以強制執行該操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.