2012-12-18 42 views
2

我绝对不擅长MySQL,但直到现在我还没有。我正在处理一个大型数据库,特别是一个具有1500多行的用户表。所以我需要弄清楚如何有效地完成我用IN子句完成的工作。MySQL中的高效子查询

这里的查询:

SELECT * 
FROM artists_profile 
WHERE artist_name LIKE '%$test%' OR id IN (SELECT profile_id 
       FROM artists_profileltp_join 
      WHERE genre_id IN (SELECT id 
           FROM artists_ltp 
           WHERE genre LIKE '%$test%') OR 
            details LIKE '%$test%') 

数据库样本数据

artists_profile   artists_profileltp_join 
+------+-------------+  +---------+------------+---------+ 
| ID | artist_name |  |genre_id | profile_id | details | 
+------+-------------+  +---------+------------+---------+ 
| 1 | Jake  |  |  1 |  2 | rap  | 
| 2 | Obama  |  |  2 |  3 | smooth | 
| 3 | Bob   |  |  1 |  1 | metal | 
+------+-------------+  +---------+------------+---------+ 
    artists_ltp 
+------+-------+ 
| ID | genre | 
+------+-------+ 
| 1 | rock | 
| 2 | jazz | 
+------+-------+ 

为$测试= “JA” 将返回artist_profile ID 1和3,因为杰克与 “JA” 开头期望的结果和鲍勃扮演包含“ja”的流派。

表格很简单。

Artists_profile包含有关用户的所有独特信息。 Artists_profileltp_join具有profile_id(int(11)),genre_id(int(11))和详细信息(varchar(200))字段,并简单地将artists_profile表连接到artists_ltp表。

artists_ltp只有一个唯一的ID和varchar(50)字段。平均需要30秒来运行我的查询。我可以做些什么来加快速度并提高子查询的效率?

回答

3
SELECT DISTINCT a.* 
FROM artist_profile a 
     INNER JOIN artists_profileltp b 
      ON a.ID = b.profile_ID 
     INNER JOIN artists_ltp c 
      ON b.genre_id = c.id 
WHERE c.genre LIKE '%$test%' OR 
     c.details LIKE '%$test%' 

JOIN在这一个会更好。但不幸的是,由于您使用的是LIKE,因此您查询的内容不会使用INDEX。我会建议你阅读FULL TEXT SEARCH

一件事一些文章,查询与SQL Injection脆弱的,请阅读下面的文章,以了解如何从中阻止,

+0

打败了我......只有我想提出的其他优化是从C中选择,加入B,加入A –

+0

非常感谢!这很好。但是,如何返回artist_profile?该查询从所有三个表中返回行。 – Colin

+0

另一个问题...从artist_profile行不一定需要链接到其他表,我仍然希望这些被返回...我更新了原始查询,以显示我的意思。 – Colin