【问题标题】:What is wrong with this query or my database? Terrible performance此查询或我的数据库有什么问题?糟糕的表现
【发布时间】:2010-05-20 02:14:40
【问题描述】:
SELECT * from `employees` a 
LEFT JOIN (SELECT phone1 p1, count(*) c, FROM `employees` GROUP BY phone1) b
ON a.phone1 = b.p1;

我不确定是否是这个查询特别有问题。总的来说,这个数据库的表现很糟糕。有问题的表有 120,000 行。我已经使用 MyISAM 和 InnoDB 引擎远程和本地尝试了这个特定的查询,使用不同类型的连接,并且在 phone1 上有和没有索引。我可以在大约 4 分钟内成功地在 10,000 行表上完成此操作,但是随着表的增大,性能会呈指数下降。远程它会失去与服务器的连接,而在本地它会使我的系统瘫痪并且似乎永远继续下去。

当较大的查询无法完成时,此查询只是我尝试执行的较小步骤。也许我应该解释整个场景。我有一个又大又丑的桌子,上面列出了一群人及其联系信息以及他们工作的公司的信息。我正在尝试规范化数据库并智能地确定哪些电话号码适用于个人,哪些适用于办公地点。我的推理是,如果一个电话号码出现多次并且出现次数等于它所附加的街道地址出现的次数,那么它必须是一个办公室号码。所以第一步是按电话号码分组统计每个电话号码。通常,如果您只使用 COUNT()...GROUP BY 它只会列出它在该组中找到的第一条记录,所以我想我必须将完整表加入到电话号码匹配的计数表中。这确实有效,但正如我所说,我无法在任何大于 10,000 行的表上成功完成它。这看起来很可悲,而且这似乎不是一个疯狂的查询。有没有更好的方法来实现我想要的,或者我必须将我的大桌子分成 12 块,还是桌子或数据库有问题?

编辑,回答 Rob 的请求:

1, 'PRIMARY', 'a', 'ALL', '', '', '', '', 60097, '' 1, '主', '', '全部', '', '', '', '', 9363, '' 2, 'DERIVED', 'employees1', 'ALL', '', '', '', '', 60097, '使用临时;使用文件排序'

【问题讨论】:

  • 你能解释一下吗...例如解释 SELECT * from employees a LEFT JOIN (SELECT phone1 p1, count(*) c, FROM employees GROUP BY phone1) b ON a.phone1 = b.p1;然后发布结果。
  • phone1 上有索引吗?
  • 哈哈,哇,我以前不知道 EXPLAIN,我就像“我以为我解释得很好”。这是我得到的。这是什么意思呢?希望它在此评论中很好地显示。 1, 'PRIMARY', 'a', 'ALL', '', '', '', '', 60097, '' 1, 'PRIMARY', '', 'ALL', '', ' ', '', '', 9363, '' 2, 'DERIVED', 'employees1', 'ALL', '', '', '', '', 60097, '使用临时;使用文件排序'
  • 哦,好吧,显示不好。大卫:我试过有没有索引,没有帮助。
  • “使用临时;使用文件排序”是您不想在 EXPLAIN 中看到的两件事。它将结果转储到磁盘上的临时表中。这样做很可能是因为 GROUP BY。

标签: mysql performance join


【解决方案1】:

如果这是一次性规范化“清理”,我会将您的子查询推送到临时表、索引中,您是否加入它,然后在完成后将其删除。

【讨论】:

  • 天哪!我从没想过这会有所作为,但现在几乎是瞬间的! (4-6 秒)起初我忘了索引临时表,但它已经是一个改进,至少它最终在 1600 行突增中开始显示结果。如果没有索引,将需要几分钟。我花了很长时间才意识到如何将我的查询进一步分解,而我一直在思考为什么我什至需要这样做。为什么我需要这样做?无论如何,非常感谢哦 Great Llama。
  • 问题是这已经是一个子子查询,我将不得不为第二个电话号码、传真和免费电话号码再做一次。哦,好吧。
猜你喜欢
  • 1970-01-01
  • 2016-06-18
  • 2010-11-24
  • 2017-02-10
  • 1970-01-01
  • 2015-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多