在IN子句中MySQL多列

nbe*_*hat 14 mysql sql where-in

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

  • X0
  • Y0
  • X1
  • Y1

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

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

我想按照这个SO答案的建议做这样的事情,但它只适用于Oracle数据库,而不适用于MySQL:

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

我以为可能有可能对索引做点什么?什么是最好的方法(即:最快的查询)?谢谢你的帮助!

笔记:

  • 我无法更改数据库的架构
  • 我有大约100'000'000行

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

spe*_*593 15

要有效地使用索引,可以重写IN谓词

(x0, y0, x1, y1) IN ((4, 3, 5, 6),(9, 3, 2, 1))
Run Code Online (Sandbox Code Playgroud)

像这样:

(  ( x0 = 4 AND y0 = 3 AND x1 = 5 AND y1 = 6 ) 
OR ( x0 = 9 AND y0 = 3 AND x1 = 2 AND y1 = 1 )
)
Run Code Online (Sandbox Code Playgroud)

  • 您的解决方案要快得多。使用我们的 MySQL 版本,单个查询(100'000'000 行,列表中有 10 个元素)使用您的解决方案需要 3.14 秒,而使用 `IN` 语法需要 1427 秒。 (2认同)

Gor*_*off 8

我不明白你的观点.以下查询是有效的MySQL语法:

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

我希望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
Run Code Online (Sandbox Code Playgroud)

WHERE条款中的相等比较利用索引.


Bil*_*win 7

MySQL允许你显示的行构造函数比较,但优化器不知道如何使用索引来帮助性能,直到MySQL 5.7.