2010-01-14 76 views
0

我担心这有点贵。任何人都可以制定出更优化的SQL解决方案吗?

另外,我将很快实现标签的标准化系统,以便有额外的连接。

最重要的是,我有4个表格(tbl_videos,tbl_articles,tbl_galleries和tbl_users),我想要显示它们的三个结果,因此将不得不在一次按下搜索时运行查询四次。

SELECT *, 
(
(CASE WHEN `description` LIKE '%hotel%' THEN 1 ELSE 0 END) + 
(CASE WHEN `description` LIKE '%london%' THEN 1 ELSE 0 END) + 
(CASE WHEN `description` LIKE '%lazy%' THEN 1 ELSE 0 END) + 
(CASE WHEN `description` LIKE '%dog%' THEN 1 ELSE 0 END) + 

(CASE WHEN `title` LIKE '%hotel%' THEN 1 ELSE 0 END) + 
(CASE WHEN `title` LIKE '%london%' THEN 1 ELSE 0 END) + 
(CASE WHEN `title` LIKE '%lazy%' THEN 1 ELSE 0 END) + 
(CASE WHEN `title` LIKE '%dog%' THEN 1 ELSE 0 END) + 

(CASE WHEN `tags` LIKE '%hotel%' THEN 1 ELSE 0 END) + 
(CASE WHEN `tags` LIKE '%london%' THEN 1 ELSE 0 END) + 
(CASE WHEN `tags` LIKE '%lazy%' THEN 1 ELSE 0 END) + 
(CASE WHEN `tags` LIKE '%dog%' THEN 1 ELSE 0 END) 

) AS relevance 
FROM `table` 
WHERE `description` LIKE '%hotel%' 
    OR `description` LIKE '%london%' 
    OR `description` LIKE '%lazy%' 
    OR `description` LIKE '%dog%' 
    OR `title` LIKE '%hotel%' 
    OR `title` LIKE '%london%' 
    OR `title` LIKE '%lazy%' 
    OR `title` LIKE '%dog%' 
    OR `tags` LIKE '%hotel%' 
    OR `tags` LIKE '%london%' 
    OR `tags` LIKE '%lazy%' 
    OR `tags` LIKE '%dog%' 
ORDER BY relevance DESC 
LIMIT 0 , 3; 
+0

什么是你正在试图解决的问题,它只是要在数据库中搜索一个给定的搜索词? 什么是过程,你有用户输入数据到搜索框然后会发生什么? – 2010-01-14 10:24:31

+0

它只是一个标准的搜索,是的。然后像Facebook一样显示每个类别的x号码列表;在我的情况下,显示3个用户,3个文章,3个视频和3个画廊作为结果。 – Mark 2010-01-14 10:29:21

+0

因此,在您的示例中,用户搜索了“酒店伦敦懒狗”? – 2010-01-14 10:57:16

回答

1

是的,这很可能将是相当渴求资源的,但它听起来就像你在前面有一个业务层提交查询之前。

想想你想要达到什么样的目的,以及在解析搜索条件方面你可以做些什么,甚至给用户提供单独的描述字段,标题和标签,并且适当地构建查询,以便更直接地该查询,而不是有效地说,“我有一些数据非常像这个搜索词,在这张表的某个位置”。一旦你确定了业务逻辑(如果上述查询是如何结束的,尽管我怀疑它,那么sobeit),那么你应该通过解释计划来运行查询,并且看看你可以选择哪个建立一些索引来帮助数据库。

编辑:

好了,这个怎么样的建议

select matched_val, relevance from (
    select description as matched_val, count(*) as relevance 
    from table 
    where description like '%hotel%' 
    or description like '%london%' 
    or description like '%lazy%' 
    or description like '%dog%' 
    group by description 

    union all 

    select title as matched_val, count(*) as relevance 
    from table 
    where title like '%hotel%' 
    or title like '%london%' 
    or title like '%lazy%' 
    or title like '%dog%' 
    group by title 

    union all 

    select tags as matched_val, count(*) as relevance 
    from table 
    where tags like '%hotel%' 
    or tags like '%london%' 
    or tags like '%lazy%' 
    or tags like '%dog%' 
    group by tags 
) as a 
order by a.relevance desc 
LIMIT 0 , 3 

它至少意味着你只需做你像匹配的一次,而不是在谓语和switch语句,再加上优化器可以在描述,标题和标签上使用索引(您将需要添加自己),并且您应该离开。

有一个去看看你的查询优化器是如何喜欢它...

+0

嗯,我得到以下错误“每个派生的表必须有它自己的别名”:长相好,否则 – Mark 2010-01-14 13:07:22

+0

看到我最新的编辑用于更格式化版本... 你可能需要做这样的事情: 通过a.relevance递减 极限0,3 我没有用mysql的选择matched_val,从( - 所有这些工会 )作为 秩序的相关性,但你必须做的SQL Server – 2010-01-14 13:32:09

+0

哇上。 ..没有错误,但它的价格远高于0.0006的0.0554秒,而结果是错误的。我认为我不能更有效率,因为每个子查询都是查询,因此它的4个查询就是一个大查询。不管怎样,谢谢你。 – Mark 2010-01-14 14:04:18

相关问题