【问题标题】:mysql query taking 30 seconds to execute...too longmysql查询需要30秒才能执行......太长了
【发布时间】:2010-08-17 15:41:59
【问题描述】:

我正在尝试在网站上运行 MySQL 查询作为搜索,但这需要很长时间。

我直接从 phpMyAdmin 运行它,大约需要 20 秒才能完成。

这是我正在运行的查询:

SELECT * , bb_business.id AS bid
FROM bb_business
LEFT OUTER JOIN bb_offers ON bb_business.id = bb_offers.store_id
LEFT OUTER JOIN bb_cat_business ON bb_business.id = bb_cat_business.store_id
LEFT OUTER JOIN bb_categories ON bb_categories.id = bb_cat_business.cat_id
WHERE bb_business.active = '1'
AND (
bb_business.business_name LIKE '%altas%'
OR bb_categories.category_name LIKE '%altas%'
OR bb_business.business_name LIKE '%juice%'
OR bb_categories.category_name LIKE '%juice%'
)
AND (
bb_business.city LIKE '%%'
OR bb_business.state LIKE '%%'
OR bb_business.zip LIKE '%%'
)
GROUP BY bb_business.business_name
ORDER BY bb_business.business_name DESC 
LIMIT 1 , 10`

速度:显示第 0 - 0 行(共 1 行,查询耗时 20.1130 秒)

我不确定向您展示结构的最佳方式。但这里复制并粘贴一些表格的排序规则:

bb_ach            128 InnoDB latin1_swedish_ci 32.0 KB - 
bb_business       2,862 InnoDB latin1_swedish_ci 1.6 MB - 
bb_categories     15 MyISAM utf8_general_ci 6.7 KB 60 Bytes

bb_cat_business   2,926 MyISAM utf8_general_ci 49.6 KB 17 Bytes

bb_emails         13 MyISAM utf8_general_ci 6.0 KB - 
bb_member         409 MyISAM utf8_general_ci 62.7 KB - 
bb_member_card    593 MyISAM utf8_general_ci 112.1 KB - 
bb_merchant       154 InnoDB latin1_swedish_ci 32.0 KB - 
bb_offers         80 InnoDB latin1_swedish_ci 16.0 KB - 
bb_products       2 InnoDB latin1_swedish_ci 32.0 KB 

如果我能提供其他任何东西。请告诉我。

非常感谢您的帮助。

编辑##################################

好的,根据 OMG Ponies 的建议,我改变了一些东西。制作了一些东西 MyISAM 并创建了一些 FULLTEXT 索引来使用。

我最终得到了这个查询:

SELECT *, bb_business.id AS bid FROM bb_business 
LEFT OUTER JOIN bb_offers ON bb_business.id = bb_offers.store_id 
LEFT OUTER JOIN bb_cat_business ON bb_business.id = bb_cat_business.store_id 
LEFT OUTER JOIN bb_categories ON bb_categories.id = bb_cat_business.cat_id 
WHERE bb_business.active = '1' AND 
MATCH(bb_business.business_name) AGAINST ('".addslashes($business)."') OR 
MATCH(bb_categories.category_name) AGAINST ('".addslashes($business)."') OR 
MATCH (bb_business.city,bb_business.state,bb_business.zip) AGAINST ('".addslashes($city)."') 
GROUP BY bb_business.business_name 
ORDER BY bb_business.imported,".$this->sortCol." ".$this->sortDirection." LIMIT ".$this->start.",".$this->limit

我认为它让它变得更慢;)

解释给出了这个:

id  select_type  table  type  possible_keys  key  key_len  ref  rows  Extra  
1 SIMPLE bb_business ALL NULL NULL NULL NULL 2877 Using temporary; Using filesort 
1 SIMPLE bb_offers ALL NULL NULL NULL NULL 94   
1 SIMPLE bb_cat_business ALL NULL NULL NULL NULL 5697   
1 SIMPLE bb_categories eq_ref PRIMARY PRIMARY 8 buxback_site.bb_cat_business.cat_id 1 Using where 

所以结果是第一个查询最多需要 40 秒才能完成。如果我再次搜索完全相同的短语,速度就像我期望的 MYSQL 执行的那样。以毫秒为单位。这只是第一次搜索需要 FOREVER...

还有什么想法吗?我很乐意花钱请人帮忙。

【问题讨论】:

  • 这些表上有哪些索引? EXPLAIN 给出了什么?
  • 您是否知道使用字段 LIKE '%%' 与 field = '%' 几乎相同,因为 %% 是您逃避百分号的方式。不确定这是否是您的意图。
  • @Finster - 它可能还强制对 bb_business 进行全表扫描...最好从查询中完全删除任何此类条目...然后我们还有 SELECT * 而不是列列表检索,以及没有任何聚合列的 GROUP BY

标签: php mysql


【解决方案1】:

从表面上看,这是我的重写:

   SELECT *, bb_business.id AS bid
     FROM bb_business b
LEFT JOIN bb_offers o ON o.store_id = b.id
LEFT JOIN bb_cat_business cb ON cb.store_id = b.id
LEFT JOIN bb_categories c ON c.id = cb.cat_id
    WHERE b.active = '1'
      AND (    bb_business.business_name LIKE '%altas%'
            OR bb_business.business_name LIKE '%juice%'
            OR MATCH(c.category_name) AGAINST ('altas', 'juice'))          
 GROUP BY b.business_name
 ORDER BY b.business_name DESC 
    LIMIT 0, 10
  • LIMIT 从零开始 - 从一开始将省略第一条记录。
  • 您可以在 MyISAM 表上使用全文搜索 (FTS) 功能,这就是 MATCH() .. AGAINST 的功能。您可以通过添加全文索引来加快速度...
  • SELECT * 是一个不好的方法 - 最好把你真正想要的每一个都写出来

【讨论】:

  • 你也可以移动business_name like to match-against
  • @ovais.tariq:全文支持仅在 MyISAM 表上 - bb_business 是 InnoDB
【解决方案2】:

使用 EXPLAIN 查看发生了什么,数据库如何执行您的数据库。

LIKE 会降低性能,当您的参数以 % 开头时,数据库不能使用任何索引。

【讨论】:

    【解决方案3】:

    只是想回来修改这个并发布答案。我最终创建了一个索引表并创建了一个 PHP 脚本来索引主数据库。底线是 MySQL 没有很好地处理跨多个表的多个匹配项。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-06
      • 1970-01-01
      • 1970-01-01
      • 2018-02-13
      • 1970-01-01
      相关资源
      最近更新 更多