【问题标题】:My SQL query is so slow it times out. Another solution?我的 SQL 查询太慢了,以至于超时。另一个解决方案?
【发布时间】:2015-12-20 11:51:21
【问题描述】:

这是一个相当复杂的问题,但我会尽力描述它。

我目前有 2 个表连接到 insta_id

第一个表名为Soc_stat,其中包含大量 Instagram 帖子条目。我在 SQL 查询中使用的列是 insta_idmain_tag

另一个表称为tags,包括一个insta_id 以及与该insta_id 一起使用的所有tag_names

ftags 表如下所示。

我当前的 SQL 查询如下所示

SELECT tag_names
FROM soc_stat
JOIN tags ON soc_stat.insta_id = tags.insta_id
WHERE main_tag = $hashtag

现在的问题是,目前我在tags 表中有 110000 行,并且上面的查询花费了很长时间,以至于它经常超时。但我想我可能已经找到了解决方案:soc_stat 表中的main_tag 始终在tags 表中的tag_names 下表示。

所以也许我不必加入这两个表?难道不能只检查tags 表中包含tag_name 等于$hashtag 的所有insta_id,然后获取链接到insta_id 的所有tag_names 吗? s?

编辑

我刚刚在我知道有问题的主题标签上的查询中添加了explain,结果如下:

在这里,我在一个使用较少的标签上完成了它,它仍然很慢,但几乎没有那么慢

【问题讨论】:

  • 您是否为表格编制了索引?
  • 两个表中 insta_id 的数据类型和大小是什么,以及如果它被索引,你如何索引它。 main_tag 的相同详细信息共享
  • 嘿MenukZ。不,我没有索引我的表。不幸的是,我对 SQL 非常陌生,并且每天都在学习。所以甚至不确定我将如何索引它们。但我确信有一个指南。我目前正在为我的数据库使用 phpadmin
  • 扎法尔。 insta_id 的数据类型为 varchar(250),tag_names 的数据类型为 varchar(65)。我没有索引任何东西。
  • 请为两张表提供SHOW CREATE TABLE

标签: mysql sql database indexing query-optimization


【解决方案1】:

在非平凡大小的表中处理 JOIN 查询时,编写显示列名的查询总是一个好主意。那是因为哪个表提供每列对性能很重要。通过阅读它也更容易理解查询的意图。

我猜你的问题;请确认您的hashtagsmain_tag 都来自您的soc_stat 表。这个查询正确吗?

SELECT soc_stat.hashtags
  FROM soc_stat
  JOIN tags on soc_stat.insta_id = tags.insta_id
 WHERE soc_stat.main_tag = $hashtag

接下来我们可以理清查询的意图。它从soc_stat 表中的每个条目返回hashtags 列,并带有您在$hashtag 中提供的main_tag 值。但它也会对tags 进行JOIN,并且从不将该表的内容用于WHERE 子句或SELECT 子句。

我猜你的查询意图是这样的:

给出与我提供的条目相关联的所有标签的集合 main_tag 值。

但您的查询并没有这样做。我相信你想要的是这样的:

SELECT DISTINCT tags.tag_names
  FROM soc_stat
  JOIN tags on soc_stat.insta_id = tags.insta_id
 WHERE soc_stat.main_tag = $hashtag

您应该验证此查询是否产生了对您有用的信息。

要让这个查询正常工作,您需要几个复合索引。在您的 soc_stat 表上,您应该将列 (main_tag, insta_id) 索引到单个实例中。为了满足您的查询,您需要在该表中找到main_tag 的特定值,然后您需要检索insta_id 的所有相关值。这种复合索引可以提高效率。

tags 上,您应该索引(insta_id, tag_names)。这是因为查询将进入知道 insta_id 的表并检索所有关联的 tag_names 值。

像这样的 DDL 命令会创建这些索引:

CREATE INDEX index_ss_mt_ii ON soc_stat (main_tag, insta_id)
CREATE INDEX index_tg_ii_tn ON tags     (insta_id, tag_names)

最后,我在查询中写了SELECT DISTINCT 以消除重复。在大型结果集中,这将需要一些时间。

请注意,现在是时候将 SQL 索引的理解添加到您的技能集中了。 SQL 的重点是从大型数据集中快速检索数据,此在线出版物非常适合此目的。 http://use-the-index-luke.com/

【讨论】:

  • 感谢您的回复。是的,我需要在 SQL 方面做得更好。我不得不承认,我发现 SQL 没有编程的其他方面那么有趣。但我正在努力,希望我最终会得到它。我知道了解数据库的最佳使用非常重要。
  • 就主题标签而言,这是一个错字。它应该被称为 tag_names。我现在已经更正了
  • SQL 可能是您必须实际使用的第一种声明性而不是过程语言。显然,你如何将你的意图翻译成这样一种语言的问题值得解决。而且,一个警告:世界上到处都是不想了解 SQL 性能的程序员。这些程序员是肆无忌惮、昂贵且无益的数据库管理员的合法猎物。
  • 是的。我在一月份完成了计算机科学教育,我毫不怀疑精通 SQL 会有多大的好处。尤其是在作为雇员为雇主增加价值时。做你正在苦苦挣扎的事情是非常费力的。我希望在考试后有时间坐下来深入探索 SQL。
【解决方案2】:

您的查询 -

SELECT hashtags FROM soc_stat 
JOIN tags on tags.insta_id = soc_stat.insta_id
WHERE soc_stat.main_tag = $hashtag

现在您可以使用explain select ...查看查询运行状况

此外,当涉及大数据时,其经常缺失的索引会使查询变慢

对于上述查询,如果尚未添加,则需要添加以下索引

alter table soc_stat add index main_tag_idx(main_tag);
alter table tags add index insta_id_idx(insta_id);

确保在添加索引之前备份表。

【讨论】:

  • 嘿,不幸的是,当谈到 SQL 时,我是个新手。我认为这可能是问题所在。因为我什至不确定这些指数是什么。但我会研究它,看看它是否可以在 phpadmin 中完成。我已经备份了所有内容。我会让你知道它是怎么回事:)
  • 这里是索引上的官方文档...dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html
  • 我尝试添加上述内容,但似乎没有解决我的问题。该死。我觉得我在我的头上。需要弄清楚如何优化这个东西,这样查询就不会那么慢了。
  • 使用expalin SELECT hashtags FROM soc_stat JOIN tags on tags.insta_id = soc_stat.insta_id WHERE soc_stat.main_tag = $hashtag 并将结果分享到问题中。确保将$hashtag 替换为一些实际值。
  • 看起来索引main_tag 没有在查询中获得。 main_tag 的数据类型是什么以及您在查询中为 main_tag 发送的值是什么,即 $hashtag
猜你喜欢
  • 1970-01-01
  • 2013-07-30
  • 2015-11-22
  • 2021-02-28
  • 1970-01-01
  • 2012-03-31
  • 2016-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多