如何解决MySQL查询导致网站停止的原因?

时间:2010-07-22 13:48:48

标签: mysql

我制作了这个脚本,首先创建一个包含当前类别所有产品的临时表。

然后我有一个搜索类,它创建一个临时表,并从它正在搜索的表上的各种不同的查询中插入产品(类别的临时表)。

在查看产品类别时,您可以搜索具有该类别的产品。

大多数情况下这很好,但是如果该类别上有太多产品,则在您进行搜索时整个网站会开始滞后。当我说整个网站时,我的意思是如果我关闭窗口并在网站上打开一个不同的页面,它仍然会滞后几分钟。

我现在不想发布任何代码,因为有很多,我不确定哪些部分需要发布。

但是我想知道是否有某种类型的mysql分析器可以告诉我发生了什么,所以我可以解决它?

更新

我被要求发布有问题的查询,因为有几个我会发布它们的描述:

#create category temp table

CREATE TEMPORARY TABLE cat_prod_table 
SELECT AVG(product_stat / DATEDIFF(NOW(), product_date_added)) as avg_hits, cart_product.* 
FROM cart_product 
WHERE (product_brand = "penn state") 
AND product_available = "yes" 
AND include_in_category = "yes" 
GROUP BY product_id

#This is how i create the temporary table to perform a search on
$this->tempTable = $tempTableName;
$qry = 'CREATE TEMPORARY TABLE '.$this->tempTable.' (id INT, score DECIMAL(12,10), UNIQUE KEY (id))';


# I do this full text search

INSERT INTO '.$this->tempTable.' (id, score)
SELECT '.$this->searchTable.'.product_id as id,
MATCH (
    product_name, product_description, product_brand, metal_type, primary_stone, product_type, product_type_sub, product_series, primary_stone_sub
)
AGAINST (
    "'.$str.'"
) as score
FROM '.$this->searchTable.'
WHERE product_available = "yes" 
HAVING score > 0  


#I do this incase the search exactly matches the product id

INSERT INTO '.$this->tempTable.' (id, score) 
SELECT product_id, 50 
FROM '.$this->searchTable.' 
WHERE product_id = "'.$str.'"
AND product_available = "yes"
ON DUPLICATE KEY UPDATE score = score + 50


#I do this incase the search exactly matches the style number

INSERT INTO '.$this->tempTable.' (id, score) 
SELECT product_id, 40 
FROM '.$this->searchTable.' 
WHERE product_manufacturer_num LIKE "%'.$str.'%"
AND product_available = "yes"
ON DUPLICATE KEY UPDATE score = score + 40


#I do a full text search in boolean mode so terms that are in more the 50% of all rows are included

INSERT INTO '.$this->tempTable.' (id, score)
SELECT '.$this->searchTable.'.product_id as id, 1 AS score
FROM '.$this->searchTable.'
WHERE product_available = "yes" 
AND MATCH (
    product_name, product_description, product_brand, metal_type, primary_stone, product_type, product_type_sub, product_series, primary_stone_sub
)
AGAINST (
    "'.$words.'"
    IN BOOLEAN MODE
)
ON DUPLICATE KEY UPDATE score = score + 1 


#I do this to so that items that are not rings will score low on a search for rings

UPDATE '.$this->tempTable.' 
LEFT JOIN '.$this->searchTable.' p
ON '.$this->tempTable.'.id = p.product_id
SET '.$this->tempTable.'.score = '.$this->tempTable.'.score / 2
WHERE MATCH (
    p.product_name, p.product_description, p.product_brand, p.metal_type, p.primary_stone, p.product_type, p.product_type_sub, p.product_series, p.primary_stone_sub
)
AGAINST (
    "bracelet earrings neckpiece necklace charm pendant watch"
    IN BOOLEAN MODE
) 

3 个答案:

答案 0 :(得分:0)

最简单的探查器是mysql中内置的'EXPLAIN'内容。它会解释(哈)每个查询使用的索引。还有一个慢查询日志,它详细说明了查询所花费的时间太长,无法完成。

'太多产品'是什么?创建临时表并复制几百条记录不应超过一秒钟。你是在复制数以千计吗?百万?如果是这种情况,那么对数据库进行分区比在每次搜索中来回传输大量数据更有意义。

答案 1 :(得分:0)

此外,您应该启用慢查询日志,它可以记录超过定义的一段时间执行的所有查询。

http://dev.mysql.com/doc/refman/5.0/en/slow-query-log.html

答案 2 :(得分:0)

如果您有权限,则应启用mysql_slow_query_log来记录超过特定阈值的查询。

然后执行上面找到的查询并使用EXPLAIN对其进行优化,并在必要时添加索引。