sql - MySQL查询优化

标签 sql mysql optimization performance

我有一个存储导入信息的数据库表。为简单起见,它类似于:

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,那么我不需要为该行找到规则 - 是否可以停止对该特定行的查询连接?同样,如果收款人为空,则也不应尝试加入。

还有其他方法可以优化它吗?我意识到进行文本连接并不理想……不确定是否有更好的方法。

最佳答案

我强烈建议您尽一切可能摆脱 JOIN 中的 REPLACE。在连接的两侧使用 REPLACE 完全消除了在任一表上使用索引的能力。

假设您可以摆脱 REPLACE(通过清理现有数据和/或新数据):

  • 如果您需要加入文本 列,每个使用一个字节 字符集,如果你申请 允许它(对于更小/更快的索引)。
  • 使 VARCHAR(N) 中的 N 尽可能小 尽你所能,因为它会影响侧面 索引的(或者可以说,使用索引 前缀)。
  • 我想你想做 search import_rules 索引 UNIQUE——那么你确定只 将得到每行返回的 1 行结果 导入数据

如果您想执行“在这种情况下不加入”规则,您可以将 AND 放入您的 WHERE 子句中。

LEFT JOIN import_rules ir ON id.payee=ir.search AND id.posted != 1

关于sql - MySQL查询优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4219216/

相关文章:

c# - SQL Server 2008——并行执行查询

php - 如何使用 PHP 从循环中插入数据库?

sql-server - 查找 "not matched"与查询 "NOT IN"

python - gekko 中的变量索引

sql - 无法在 Postgresql 中添加约束

mysql - inner self join的呈现顺序

Mysql replace() 函数,帮助查询(我要转义哪些字符?)

mysql - 我可以在 MySQL 的 CASE...END 子句的一个 WHEN 中放入两个(或多个)条件吗?

php - 如果数据位于 "Portuguese"中,如何使用 zend db select 获取数据?

haskell - 列表理解中的表达式是否被冗余评估?