簡體   English   中英

MySQL查詢優化

[英]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 (通過清除現有數據和/或新數據):

  • 如果需要在文本列上進行連接,請在您的應用程序允許的情況下,為每個字符字符集使用一個字節(用於更小/更快的索引)。
  • 使NVARCHAR(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM