【问题标题】:MySQL MAX_JOIN_SIZE Error! Need to optimize queryMySQL MAX_JOIN_SIZE 错误!需要优化查询
【发布时间】:2009-10-14 12:58:17
【问题描述】:

我运行这个查询:

SELECT u.user_id, u.fname, u.lname, n.title, n.news_id, n.post, 
n.zip, z.city,z.state_abbr
FROM yc_users u, yc_news n, yc_zipcodes z
WHERE u.user_id = n.user_id AND n.zip = z.zip
ORDER BY n.stamp
LIMIT 10

并得到这个错误:

The SELECT would examine more than MAX_JOIN_SIZE rows; 
check your WHERE and use SET SQL_BIG_SELECTS=1 or 
SET SQL_MAX_JOIN_SIZE=# if the SELECT is okay

yc_zipcodes 下有超过 42,000 行。目前其他表的行数不足 10 行。

编辑:按要求提供数据样本:

yc_zipcodes

zip   city        state_abbr
00210   Portsmouth  NH
00211   Portsmouth  NH
00212   Portsmouth  NH
00213   Portsmouth  NH

yc_users

user_id  username    password                           fname    lname      email              zip   active_bln
1          fission1    e09dc84a23fd6cd68ce1fff1ff95713a   Hayden   Ferguson   xxxxxx@gmail.com   92831  1
2          jason       c2d0d212936c4bfd7f587607e6c72808   jason    stevenson  xxxxxx@gmail.com   93710  1

yc_news

news_id user_id   title                         post                                            zip    stamp     active_bln
2      1         Gummy bear falls into manhole    OMG! A drunk man dressed as gummy  bear...      93740 2009-10-12 09:49:04 1
3      1         Guy robbed                       Some dude got robbed last night at corner of... 93740 2009-10-12 09:50:19 1

上面的数据是无效的。在制作这个应用程序的过程中没有小熊软糖=D

【问题讨论】:

  • 您应该根据需要指定 LEFT JOIN 或其他特定的连接类型。
  • 设置“SQL_BIG_SELECTS=1”后它工作正常,但我不喜欢这样做。它告诉我我的查询过于臃肿。

标签: mysql


【解决方案1】:

您应该使用 JOIN,而不仅仅是从所有表中选择。如果从所有表中进行选择,则会生成所有可能的行组合(这是很多),然后 WHERE 会过滤掉不需要的行。

使用这个,例如:

SELECT       u.user_id, 
             u.fname, 
             u.lname, 
             n.title, 
             n.news_id, 
             n.post, 
             n.zip, 
             z.city,
             z.state_abbr
FROM         yc_users u
INNER JOIN   yc_news n 
ON           u.user_id = n.user_id
INNER JOIN   yc_zipcodes z
ON           n.zip = z.zip
ORDER BY     n.stamp
LIMIT        10

编辑:

我在您的查询中看不到任何明显的问题。我会按照错误消息告诉您的方式设置选项,然后查看结果是否是您想要的结果。如果是 - 很好。如果不是 - 回来告诉我们。

【讨论】:

  • 我才刚刚开始使用数据库查询。我真的不知道如何使用JOINS。我已经阅读了一些教程,但我仍然感到困惑。我的所有查询似乎都不起作用。可以举个例子吗?
  • 您确定您的表中只有 42.000 行吗?
  • 能否提供一些示例数据?例如,yc_users中与单个用户相关的所有表中的数据?
  • 所涉及的其他表(yc_users 和 yc_news)的记录数是多少?因为 max_join_size 的默认值似乎是 4,294,967,295。见:dev.mysql.com/doc/refman/5.0/en/…
  • 现在每个都在 20 岁以下。但可能会达到更多。
【解决方案2】:

您的目标应该是减少结果集的大小 - 确保连接将更快地过滤所需的记录;更仔细地选择索引应该对此有所帮助。

  • 您是否(至少)在 yc_users.id 或 yc_news.id 和 yc_zipcodes.zip 上有索引?
  • 尝试在不使用 ORDER BY 的情况下运行查询,看看是否有所不同

另请参阅这些相关的 StackOverflow 线程:

有关MAX_JOIN_SIZESQL_BIG_SELECTS 的更多详细信息来自官方MYSQL 文档。

【讨论】:

    【解决方案3】:

    您的 WHERE 子句等同于 INNER JOIN(尽管我通常更喜欢显式 JOIN)并且似乎可以正确连接,不会导致意外的 CROSS JOIN。

    您使用的是什么版本的 MySQL?

    【讨论】:

    • MySQL 版本 5.0.77。使用 phpMyAdmin。
    【解决方案4】:

    虽然查询可能会更优化一些(取决于您要完成的工作),但我看不出如何将其更改为在显示信息时不会触发错误的点。正如接受的答案here 所述,您可能对连接和设置 SQL_BIG_SELECTS=1 没问题。

    不过,话虽如此,我会评估您进行连接的必要性,并可能会打开另一个问题,其中提供有关您尝试使用查询的数据完成什么的更多信息。

    乍一看,我可以假设您正在获取用户制作的所有文章以及它们来自哪里。如果是这种情况,我会向用户 LEFT JOIN news 并在另一个查询中获取 zip 关系。

    【讨论】:

      猜你喜欢
      • 2016-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-14
      • 2013-11-18
      • 2010-11-01
      • 2011-08-05
      相关资源
      最近更新 更多