Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MySQL multiple columns in IN clause

I have a database with four columns corresponding to the geographical coordinates x,y for the start and end position. The columns are:

  • x0
  • y0
  • x1
  • y1

I have an index for these four columns with the sequence x0, y0, x1, y1.

I have a list of about a hundred combination of geographical pairs. How would I go about querying this data efficiently?

I would like to do something like this as suggested on this SO answer but it only works for Oracle database, not MySQL:

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

I was thinking it might be possible to do something with the index? What would be the best approach (ie: fastest query)? Thanks for your help!

Notes:

  • I cannot change the schema of the database
  • I have about 100'000'000 rows

EDIT: The code as-is was actually working, however it was extremely slow and did not take advantage of the index (as we have an older version of MySQL v5.6.27).

like image 541
nbeuchat Avatar asked Jun 22 '17 17:06

nbeuchat


People also ask

Can we use multiple columns in WHERE clause?

But the WHERE.. IN clause allows only 1 column.

Can we use two columns in WHERE clause in SQL?

Answer. Yes, within a WHERE clause you can compare the values of two columns. When comparing two columns in a WHERE clause, for each row in the database, it will check the value of each column and compare them.

How do I subquery with multiple columns?

If you want compare two or more columns. you must write a compound WHERE clause using logical operators Multiple-column subqueries enable you to combine duplicate WHERE conditions into a single WHERE clause.

How set multiple columns in MySQL?

MySQL UPDATE command can be used to update multiple columns by specifying a comma separated list of column_name = new_value. Where column_name is the name of the column to be updated and new_value is the new value with which the column will be updated.


2 Answers

To make effective use of the index, you could rewrite the IN predicate

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

Like this:

(  ( x0 = 4 AND y0 = 3 AND x1 = 5 AND y1 = 6 )  OR ( x0 = 9 AND y0 = 3 AND x1 = 2 AND y1 = 1 ) ) 
like image 140
spencer7593 Avatar answered Sep 21 '22 21:09

spencer7593


I do not understand your point. The following query is valid MySQL syntax:

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

I would expect MySQL to use the composite index that you have described. But, if it doesn't you could do:

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 

The equality comparisons in the WHERE clause will take advantage of an index.

like image 40
Gordon Linoff Avatar answered Sep 22 '22 21:09

Gordon Linoff