MySQL IN 子句中的多列

MySQL multiple columns in IN clause

我有一个数据库,其中有四列对应于开始和结束位置的地理坐标 x,y。这些列是:

我有这四列的索引,序列为 x0、y0、x1、y1。

我有大约一百个地理对组合的列表。我将如何有效地查询这些数据?

我想按照 this SO answer 上的建议做类似的事情,但它只适用于 Oracle 数据库,不适用于 MySQL:

SELECT * FROM my_table WHERE (x0, y0, x1, y1) IN ((4, 3, 5, 6), ... ,(9, 3, 2, 1));

我在想也许可以对索引做些什么?什么是最好的方法(即:最快的查询)?感谢您的帮助!

备注:

编辑: 原样的代码实际上可以工作,但是它非常慢并且没有利用索引(因为我们有 MySQL v5.6.27 的旧版本)。

您可以 concatenate 将四个值放入一个字符串中并像这样检查它们:

SELECT * 
FROM my_table 
WHERE CONCAT_WS(',', x0, y0, x1, y1) IN ('4,3,5,6', ..., '9,3,2,1');

我不明白你的意思。以下查询是有效的 MySQL 语法:

SELECT *
FROM my_table
WHERE (x0, y0, x1, y1) IN ((4, 3, 5, 6), ... ,(9, 3, 2, 1));

我希望 MySQL 使用您描述的复合索引。但是,如果不行,您可以这样做:

SELECT *
FROM my_table
WHERE x0 = 4 AND y0 = 3 AND x1 = 5 AND y1 = 6
UNION ALL
. . .
SELECT *
FROM my_table
WHERE x0 = 9 AND y0 = 3 AND x1 = 2 AND y1 = 1

WHERE 子句中的相等比较 利用索引。

为了更有效地利用索引,您可以重写 IN 谓词

(x0, y0, x1, y1) IN ((4, 3, 5, 6),(9, 3, 2, 1))

像这样:

(  ( x0 = 4 AND y0 = 3 AND x1 = 5 AND y1 = 6 ) 
OR ( x0 = 9 AND y0 = 3 AND x1 = 2 AND y1 = 1 )
)

您的做法是在我机器上的 mysql 版本中给出正确的结果。我正在使用 v5.5.55。也许您正在使用旧的。请检查。

如果您仍然想在您自己的版本中解决此问题,或者上述解决方案不起作用,那么请阅读下一个解决方案。

我仍然不清楚这里所有列的数据类型和范围。所以我假设数据类型是整数,范围在 0 到 9 之间。如果是这种情况,您可以按照下面的说明轻松地执行此操作。

select * from s1 where x0+10*x1+100*y1+1000*y2 in (4356,..., 9321);

MySQL 允许像您显示的那样进行行构造函数比较,但优化器直到 MySQL 5.7.

才知道如何使用索引来帮助提高性能