Mysql 在 case when 语法中使用索引
Mysql use of index in case when syntax
我正在编写一个使用以下语法更新的查询:
UPDATE foo SET col1 = CASE col2
WHEN 1 THEN 3
WHEN 2 THEN 9
...
ELSE col1 END
WHERE col2 IN (1,2...)
请注意,WHEN THEN 情况可能有数千种。 EXPLAIN 显示 PK 将用于 IN 子句,但是数据库在根据 IN 子句过滤后如何计算 CASE/WHEN - 它是扫描所有它们还是使用哈希?我不认为这在 EXPLAIN 中是明确的(例如没有 IN 子句)。
代替数千个 case when 语句,在您的数据库中创建另一个 table(我们将其命名为 keyValueTable)并让一列为 when
(键),另一列为 then
(值):
id colkey value
1 1 3
2 2 9
使colkey
唯一并在其上设置索引,然后像
一样查询数据库
UPDATE foo SET col1 = (
SELECT value from keyValueTable
INNER JOIN foo ON keyValueTable.colkey = foo.col1
LIMIT 1
)
WHERE ...
对于未被 WHERE
筛选的每一行,CASE
表达式将被繁琐地遍历。没有优化,因为 WHEN
值可以是任意表达式,而不是像您的情况那样的简单常量。
这可能会更快,假设您在 col2 上有一个索引:
UPDATE foo SET col1 = 3 WHERE col2 = 1;
UPDATE foo SET col1 = 9 WHERE col2 = 2;
...
我正在编写一个使用以下语法更新的查询:
UPDATE foo SET col1 = CASE col2
WHEN 1 THEN 3
WHEN 2 THEN 9
...
ELSE col1 END
WHERE col2 IN (1,2...)
请注意,WHEN THEN 情况可能有数千种。 EXPLAIN 显示 PK 将用于 IN 子句,但是数据库在根据 IN 子句过滤后如何计算 CASE/WHEN - 它是扫描所有它们还是使用哈希?我不认为这在 EXPLAIN 中是明确的(例如没有 IN 子句)。
代替数千个 case when 语句,在您的数据库中创建另一个 table(我们将其命名为 keyValueTable)并让一列为 when
(键),另一列为 then
(值):
id colkey value
1 1 3
2 2 9
使colkey
唯一并在其上设置索引,然后像
UPDATE foo SET col1 = (
SELECT value from keyValueTable
INNER JOIN foo ON keyValueTable.colkey = foo.col1
LIMIT 1
)
WHERE ...
对于未被 WHERE
筛选的每一行,CASE
表达式将被繁琐地遍历。没有优化,因为 WHEN
值可以是任意表达式,而不是像您的情况那样的简单常量。
这可能会更快,假设您在 col2 上有一个索引:
UPDATE foo SET col1 = 3 WHERE col2 = 1;
UPDATE foo SET col1 = 9 WHERE col2 = 2;
...