2013-03-30 102 views
3

我目前上传datafeeds到我的数据库。在我的数据库被转储,因为超过1crores记录在那里。我需要改善或提高我的MYSQL查询性能在我的网站。这里我执行查询下面....如何提高MYSQL查询的性能?

select SUM(SPRICE) AS Tot, MIN(SMIN) AS Min from 
(SELECT COUNT(LS.SALEPRICE) AS SPRICE, MIN(LS.SALEPRICE) AS SMIN 
FROM `linkshare` LS 
WHERE LS.`PRODUCTNAME` LIKE '%DVS Men\'s Comanche Skate Shoe%' 
UNION 
SELECT COUNT(CJ.PRICE) AS SPRICE, MIN(CJ.PRICE) AS SMIN 
FROM `cjfeeds` CJ 
WHERE CJ.NAME LIKE '%DVS Men\'s Comanche Skate Shoe%') AS xyz 

在这上面的查询,其在本地数据库完美的工作和我的数据库包含较少的5万多条记录...如何提高我在直播服务器查询?请指导我.....

Explain Query

另外我的查询耗时39.4626秒。我怎样才能减少这个查询运行时间?

+0

您需要规范化数据库。 –

+0

[选择比费雪价格我的第一个SQL Server](http://grimoire.ca/mysql/choose-something-else)?如果你想要一个严肃的评论:你的LIKE与通配符匹配,你的字符串的开始和结束可能对你的查询造成最大的伤害。 –

+1

请注意,您应该在查询中使用'UNION ALL'而不是'UNION'(默认为'UNION DISTINCT')。 –

回答

0

使用EXPLAIN找出什么是引擎盖下回事

3

确定,要与你的查询更具体的编辑我的回答对第一笔交易,早前建议的工作,但你的查询是相当疯狂让我们讨论为什么。

您需要的一切实际上都是在EXPLAIN输出中,您的UNION正在导致340万个元组访问,并且派生表查询(连接之后)大约是90万元。

  • Add an index上PRODUCTNAME两个表

  • 联盟?跆拳道?我假设这里发生了什么是你有两个相似/相同的表,你正在做一个这个相当不友好的过滤器查询的联盟,以基本上连接到另一个。 这是第一个警告标志,如果您可以简化此操作并且使用一个枚举类型为enum的表(例如, type(LS | CJ)或外键和类型表,具体取决于您的要求。

  • 假设你不想因为某种原因永久性地完成这个操作(你应该),你可以从这两个选择中对这个计算执行create a temporary table。一旦你把所有信息放在一张表中,因为你正在做一个简单的选择你的计数,总和会很快。

MySQL有一个EXPLAIN命令,您可以在任何查询中加前缀,例如

EXPLAIN select SUM(SPRICE) AS Tot, MIN(SMIN) AS Min from (SELECT COUNT(LS.SALEPRICE) AS SPRICE, MIN(LS.SALEPRICE) AS SMIN FROM `linkshare` LS WHERE LS.`PRODUCTNAME` LIKE '%DVS Men\'s Comanche Skate Shoe%' UNION SELECT COUNT(CJ.PRICE) AS SPRICE, MIN(CJ.PRICE) AS SMIN FROM `cjfeeds` CJ WHERE CJ.NAME LIKE '%DVS Men\'s Comanche Skate Shoe%') AS xyz; 

对于初学者来说,输出可能有点神秘,请查看tutorial了解更多信息。总的来说:

  • 尽可能避免'LIKE%blah%'风格查询,因为Mark Ba​​nnister建议这些查询不会使用您创建的任何索引。
  • 在选择中使用的任何字段(在具有超过一千行的表格中)创建索引。
  • 保持快速增长的表格尽可能地精益
  • 尽可能使用固定宽度的列, char/varchar而不是TEXT/BLOB
  • 如果您在大型数据集上运行复合缓慢查询,请考虑缓存它/ mygof表缓存大小/ tuning

    总之,总是尝试做精确的字符串匹配,因为它们可以被索引。你的问题源于规范化程度较低的表格结构。规范化只是意味着(以高级别的非技术方式),您已经以减少重复的方式组织数据,因此更加一致。这样做的好处是它可以更容易地对其进行有效的查询。 如果您认为需要通配符查询,则可能需要将产品分类为 分成'shoes'这样的类别,为此,请添加一个product_categories表,其中包含类似于| category_id,category_name |的模式。然后在你的产品表中(如果一个产品只能在一个类别中)添加一个外键,例如category_id,向category_id字段添加索引,然后通过category_id查询产品

例如, select * FROM products where category_id = 5

如果您认为您需要对数据进行模糊匹配,那么确实听起来好像有点混乱。如果这是不可避免的,那么看看你的devops人员是否可以设置一个读取从属设备,这样你的缓慢查询就不会伤害任何重要的系统。

+0

如果你错误地组装它,那么调整引擎是毫无用处的。 –

+1

请注意,'''blah%'''可能可以使用索引,但'like'%blah%''不太可能使用索引。 –

+0

我在价格字段中创建了索引。但我如何在我的查询中使用这个索引。 –

-1

您可能会看到在性能小的改进,如果你改变你的查询是:

select SUM(SPRICE) AS Tot, MIN(SPRICE) AS Min from 
(SELECT SALEPRICE SPRICE 
FROM `linkshare` 
WHERE `PRODUCTNAME` LIKE '%DVS Men\'s Comanche Skate Shoe%' 
UNION ALL 
SELECT PRICE SPRICE 
FROM `cjfeeds` 
WHERE NAME LIKE '%DVS Men\'s Comanche Skate Shoe%') AS xyz 

- 但是,你不可能永远能够显著提高你的表现;您正在执行的唯一选择是在LIKE '%DVS Men\'s Comanche Skate Shoe%'的字段中,该字段将无法使用索引,因此需要全表扫描这两个表才能派生结果。

+0

Hi @Mark Ba​​nnister,我的查询使用少量数据在本地数据库中工作。但我的实时数据库表包含超过1000万条记录。所以它需要更多的加载... –