简体   繁体   中英

optimize this mysql php query

Could you please help me in optimizing this mysql query or any other way of writing this mysql query, it runs but it takes too much time.

SELECT DISTINCT
    A.item1,
    A.item2,
    A.item3,

FROM tableAA AS A
INNER JOIN(tableBB AS B)
ON(A.item4 = B.item4)
INNER JOIN(tableCC AS C)
ON(A.item4 = C.item4)
INNER JOIN(tableDD AS D)
ON(A.item4 = D.item4)
WHERE (B.item5 = '$selected1' AND
  B.item6 LIKE '%$selected2%' AND
  C.item7='$selected3' ) OR
  (A.item8 LIKE '%$selected2%' AND
D.item5 = '$selected1' AND
 C.item7='$selected3')

Is there any other way of writing this query?

edit: tableAA & tableBB & tableCC contains billions of entry, i think i have index the tables correctly.

edit2: But i think the problem is not in Like % condition. I have switched it off and again run the query. but it is still taking long like 565 seconds.

A few obvious things to do.

1) index item4 on tables A, B, C and D. Generally, indexes speed reads (wheres and joins) and slow down writes.

2) index the columns you do a lot of straight "where"s on - B.item5, etc. But not B.item6 where the index will change nothing with your "like" matching.

3) This last one takes more time, but it's very important if you have to search using like "%$key%", because these are very time consuming - pretty much every character of every string in the column is compared to your search string: create tables where search keywords for B.item6 and A.item8 are listed, indexed, and search through them. If you do you'll make binary search possible on these columns - an enormous change.

======== EDIT: you say indexing is done, so more on point 3 above. ============

Suppose you have one table to search:

table A
-------
k (PK)
s (big string)

And you want to do:

select k
from A
where s like '%$keyword%'

s being a long string, searching through every occurrence of s for the keyword, in an unknown place, is going to be hugely time-consuming.

So we create 1 more tables:

table s_words
-------------
word | (PK)
k *  |

s_words is a list of words found in s, with the key to find the corresponding rows in table A. Each word occurs multiple times, often many times in the table. To populate s_words, you need to take all strings in s, parse them, and add each word to the table.

Now your query is:

select k
from s_words
where word = '$keyword'

Now word can be indexed, there's no need for character by character matching of the string to the user keyword.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM