简体   繁体   English

调整SQL查询。 如何将IN更改为更快的内容

[英]Tuning SQL query. How to change IN to something that is faster

I have a website that is running a query off to Mysql when a search term is entered. 输入搜索词后,我有一个网站正在对Mysql进行查询。 I built a sql statement like this 我建立了这样的sql语句

SELECT * FROM catelogue
WHERE `DEPARTMENT` LIKE 'MUSIC'
AND ( `ARTIST` LIKE '%$theValue%' OR `TITLE` LIKE '%$theValue%' OR 
    `CAT NO.` IN 
    (SELECT `TRACKLISTING CAT NO.`
    FROM tracklisting 
    WHERE `ARTIST` LIKE '%$theValue%' OR `TRACK TITLE` LIKE '%$theValue%'))
    ORDER BY `RELEASEDATE` DESC

It worked great on wamp locally when testing. 测试时,它在本地沼泽上效果很好。 Now I have uploaded the site to my host and the query seems to be crashing or slowing it down that it doesn't even load the page. 现在,我已将该站点上传到主机,查询似乎崩溃或变慢,甚至没有加载页面。

I redesigned the query to this 我重新设计了这个查询

SELECT `ARTIST` , `TITLE` , `CAT NO.` , `FORMAT` , `DEPARTMENT` , `SELL`,`IMAGE PATH` 
        FROM catelogue
WHERE `DEPARTMENT` LIKE 'MUSIC'
AND ( `ARTIST` LIKE '%$theValue%' OR `TITLE` LIKE '%$theValue%') 
    ORDER BY `RELEASEDATE` DESC"

As this stands it works great on my host now but I can't search my tracklisting table. 就目前而言,它现在可以很好地在我的主机上运行,​​但是我无法搜索我的跟踪列表。 I need to know how to change IN to something that works faster. 我需要知道如何将IN更改为更快的工作方式。

The catelogue and tracklisting table are linked by the CAT NO. 目录和跟踪列表通过目录号链接。

Thanks 谢谢

EDIT 编辑

A BIG THANKS TO EVERYONE THAT HELPED 非常感谢所有人的帮助

Now onto some bad news. 现在来看一些坏消息。 This is the code I'm using now. 这是我现在使用的代码。 It doesn't return any errors but it also doesn't return any results either 它不返回任何错误,但也不返回任何结果

SELECT c.`ARTIST` , c.`TITLE` , c.`CAT NO.` , c.`FORMAT` , c.`DEPARTMENT` , c.`SELL` 
FROM    catelogue c
LEFT JOIN   tracklisting t
        ON  t.`TRACKLISTING CAT NO.` = c.`CAT NO.`
WHERE   'DEPARTMENT' = 'MUSIC'
        AND ((  c.`ARTIST` LIKE '%$theValue%' OR c.`TITLE` LIKE '%$theValue%')
                OR
                (t.`ARTIST` LIKE '%$theValue%' OR t.`TRACK TITLE` LIKE '%$theValue%'))

The tracklisting table doesn't have all the tracklistings for every entry in the catelogue table. 跟踪列表并不包含目录表中每个条目的所有跟踪列表。 Would that make a difference? 那会有所作为吗?

I know in ms access you can setup relationships with tables, but I have been unable to figure out if this can be done in phpmyadmin, do I have to setup a relation between the tables for this to work? 我知道在ms access中可以设置与表的关系,但是我无法弄清楚这是否可以在phpmyadmin中完成,我是否必须在表之间设置一个关系才能起作用?

Many Thanks 非常感谢

Well, I don't really do PHP so some of your syntax is a little foreign to me but sql is sql and I've just copied the bits I'm not used to. 好吧,我并不是真的做PHP,所以您的某些语法对我来说有点陌生,但是sql是sql,我只是复制了我不习惯的位。

This should do what you want: 这应该做您想要的:

SELECT  *
FROM    catelogue c
    LEFT JOIN   tracklisting t
        ON  t.`TRACKLISTING CAT NO.` = c.`CAT NO.`
WHERE   `DEPARTMENT` = 'MUSIC'
        AND ((  c.'ARTIST' LIKE '%$theValue%' OR c.'TITLE' LIKE '%$theValue%')
                OR
                (t.`ARTIST` LIKE '%$theValue%' OR t.`TRACK TITLE` LIKE '%$theValue%'))
ORDER BY    `RELEASEDATE` DESC

By the way, the field naming in this database is just terrifying IMHO. 顺便说一句,在该数据库中的字段命名只是吓人恕我直言。 It would also probably help if you could do some form of full text indexing so that these "contains" LIKE comparisons don't cause you to do full table scans every time. 如果您可以进行某种形式的全文索引编制,这样这些“包含” LIKE比较不会导致您每次都进行全表扫描,那也可能会有所帮助。 Just a thought. 只是一个想法。

You can use join the two tables instead of using in clause: 您可以使用联接两个表而不是使用in子句:

SELECT 
    C.`ARTIST` , 
    C.`TITLE` , 
    C.`CAT NO.` , 
    C.`FORMAT` , 
    C.`DEPARTMENT` , 
    C.`SELL`, 
    C.`IMAGE PATH` 
FROM catelogue C LEFT JOIN tracklisting T
    ON C.`CAT NO.` = T.`TRACKLISTING CAT NO.`
WHERE 
    C.`DEPARTMENT` = 'MUSIC'
    AND (C.`ARTIST` LIKE C.'%$theValue%' OR C.`TITLE` LIKE '%$theValue%') 
    AND (T.`ARTIST` LIKE T.'%$theValue%' OR T.`TRACK TITLE` LIKE '%$theValue%')
ORDER BY 
    `RELEASEDATE` DESC

Note that I changed first condition from LIKE to = (faster) and consider that performance is affected by availability of indexes and by the structure of your query; 注意,我将第一个条件从LIKE更改为=(更快),并认为性能受索引可用性和查询结构的影响; for example you can: 例如,您可以:

  • evaluate if you can do likes without the first % 评估是否可以在没有前%的情况下进行点赞
  • if so, you can add an indexes on C. ARTIST and C. TITLE and one on T. ARTIST and T. TRACK TITLE 如果是这样,您可以在C. ARTIST和C. TITLE上添加一个索引,在T. ARTIST和T. TRACK TITLE上添加一个索引
  • add an index on C. DEPARTMENT 在C DEPARTMENT上添加索引

I didn't tested this query, but I think its a good start. 我没有测试此查询,但我认为这是一个不错的开始。 Use LEFT join insted of your structure: 使用LEFT连接插入您的结构:

SELECT * FROM catelogue  c
LEFT JOIN  tracklisting  t
ON c.`CAT NO.` = t.`TRACKLISTING CAT NO.`
WHERE c.`DEPARTMENT` LIKE 'MUSIC'
AND ( c.`ARTIST` LIKE '%$theValue%' OR c.`TITLE` LIKE '%$theValue%')
OR (t.`ARTIST` LIKE '%$theValue%' OR t.`TRACK TITLE` LIKE '%$theValue%')
ORDER BY c.`RELEASEDATE` DESC

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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