为什么我的搜索在我的主机上这么慢?

时间:2012-01-30 14:27:35

标签: mysql sql

让我先说我有一个excel spreedsheet,我的所有数据都在catelogue中。它有27个领域。随着数据的重复,许多这些字段可以拆分为单独的表。我将此表作为csv导入mysql,当我使用wamp进行测试时,它工作正常。在mysql中有2个表,我已经解释了这个表,然后另一个表跟踪列表。这有许多记录链接到catelogue表。我的SQL看起来像这样搜索

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

是的,这完全适用于我希望它如何工作但不幸的是它在我的主机服务器上根本不起作用。

所以我在堆栈溢出的几个人的帮助下转向了这个

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

现在这确实起了作用,但是每个有跟踪列表的项目都返回了该专辑中有多少曲目。 Lady Gaga有15首曲目和15首重复曲目。现在没有任何反对帮助我的人,我对这个帮助很有帮助,这比我原来的要快,但还是花了一些时间。它确实加载了页面,但没有我想要的那么快。

我已经转移到这里,所以我的搜索速度很快,但它没有搜索我的跟踪列表。

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

所以我的问题是,如何获取一个SQL语句来搜索我的catelogue和我的跟踪列表,而不需要FOREVER这样做或返回重复项。

如果前两个查询并返回CAT NO,则3个单独的查询工作会更快。到一个数组,然后在PHP中使用foreach语句的第三个?

我的所有数据库都保存为InnoDB。

由于

道歉对于缓慢的回应

所以更新

我自己做了一些测试。 Duno有多么有效但是我的原始查询使用IN语句在我的本地主机上使用wamp需要0.3到0.4秒。

连接似乎需要大致相同的时间。区别也是一样的。第一个不同的花了一秒钟,但之后它以.3或.4倍的速度运行

我的上一个没有连接的简单查询或仅仅搜索一个表的In,大约需要0.1秒。

现在我不想了解这一点,但这似乎很快。

唯一适用于主机服务器的查询是基本查询。插入也很好,但也很简单。

所以我的新问题。

我的ISP是不是很愚蠢,不允许在我的SQL中加入任何联接或In,只是冷静地告诉你你在做什么是不可能做到的?

3 个答案:

答案 0 :(得分:0)

尝试此操作以消除重复项。由于返回的数据较少,您也可以更快地找到它:

SELECT distinct c.*
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

答案 1 :(得分:0)

这里面临的最大问题是MySQL无法使用任何索引来加速以通配符开头的查询。任何其他数据库服务器都不能。它需要一个完整的表表扫描来查找每个可能的结果。添加订单声明,您强制扫描所有内容,没有提前退出条件。

您可以使用MySQL全文搜索,这很容易,因为它始终可用,或使用外部全文搜索实用程序,如Sphinx,ElasticSearch,Solr或其他。有很多选择。

否则,您也可以通过使用单词表并将内容编入索引来自己完成工作。但是,我不推荐这个选项。

答案 2 :(得分:0)

你可以把

SELECT  *
FROM    catelogue c   
WHERE   c.`DEPARTMENT` = 'MUSIC'
    AND ((  c.'ARTIST' LIKE '%$theValue%' OR c.'TITLE' LIKE '%$theValue%')

SELECT *
FROM tracklisting t
WHERE 
     (t.`ARTIST` LIKE '%$theValue%' OR t.`TRACK TITLE` LIKE '%$theValue%'))

在两个临时表中,然后LEFT JOIN,在这两个临时表上执行DISTINCT和ORDER BY。