【问题标题】:MySQL error #1104 - The SELECT would examine more than MAX_JOIN_SIZE rows;MySQL 错误 #1104 - SELECT 将检查超过 MAX_JOIN_SIZE 行;
【发布时间】:2013-11-16 19:36:18
【问题描述】:

我有一个小型非营利组织的捐赠者和门票销售信息数据库。我正在尝试根据捐赠、购买季票或购买单张票的人快速导出邮件列表。 “实体”表是联系信息等,然后其他表保存有关捐赠的信息(年份、金额、检查日期等),并有一个“实体号”字段,它与实体的主键匹配.recordno.

这是我正在运行的查询:

SELECT *
FROM
    entity
    LEFT JOIN individual_donation ON entity.recordno = individual_donation.entityno
    LEFT JOIN season_tickets ON entity.recordno = season_tickets.entityno
    LEFT JOIN single_tickets ON entity.recordno = single_tickets.entityno
WHERE 
entity.ind_org = 'ind' AND
entity.address1 <> "" AND
(individual_donation.year <> 'NULL'
OR season_tickets.year <> 'NULL'
OR single_tickets.year <> 'NULL')
GROUP BY entity.lastname
ORDER BY entity.lastname ASC

这个数据库在 BlueHost 上,我通过 PHPmyadmin 访问它。奇怪的是,当我在 PHPmyadmin 中预览时,查询运行得很好——它返回 216 行,我可以在 SQL 命令浏览器中查看所有行,并且加载得很好。

问题是每次在查询结果操作下使用PHPmyadmin的“export”命令,都会报如下错误:

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

每个表最多只有大约 300-400 行,所以我很惊讶我收到了 MAX_JOIN_SIZE 错误。我也很奇怪 sql 查询按原样工作得很好,但不能在导出上工作??

我确信我可以做更好的 JOIN 等,但我不明白为什么查询运行良好,但不会导出。

编辑: 这是 EXPLAIN EXTENDED 结果

id  select_type table               type    possible_keys   key key_len ref rows    filtered    Extra
1   SIMPLE      entity              ALL NULL        NULL    NULL    NULL    429 100.00      Using where; Using temporary; Using filesort
1   SIMPLE      individual_donation     ALL NULL        NULL    NULL    NULL    221 100.00  
1   SIMPLE      season_tickets          ALL NULL        NULL    NULL    NULL    102 100.00  
1   SIMPLE      single_tickets          ALL NULL        NULL    NULL    NULL    217 100.00      Using where

更多信息: 奇怪 - 我的虚拟主机不允许 mysql 用户具有 FILE 权限,所以我不能使用 EXPORT INTO。我尝试使用 ssh 访问,将查询运行到 > 到一个文件中,我得到了 MAX_JOIN_SIZE 错误。我仍然不明白为什么它可以在浏览器的 phpmyadmin 查询中正常工作,但不能在 phpmyadmin 中导出,也不能从命令行工作。

【问题讨论】:

  • SELECT @@max_join_size 的输出是什么?默认值为 4294967295。
  • 输出为 1000000000。
  • 十亿?这还是相当高的。即使是这几百行中的偶然full Cartesian product 也不太可能达到这个数字。您能否在查询中添加EXPLAIN EXTENDED 并将其编辑到您的问题中?
  • 添加了上面的 EXPLAIN EXTENDED 结果,以及更多注释。

标签: php mysql sql phpmyadmin


【解决方案1】:

更好地处理索引似乎解决了我的问题,尽管仍然不确定原因。

我确保三个引用表中的“entityno”列,即对实体表中主键的引用,被设置为索引。这似乎已经解决了在我的查询的某个中间步骤中导致大量返回行的任何问题。作为参考,这现在是解释扩展结果:

id      select_type     table                   type    possible_keys   key             key_len ref                             rows    filtered        Extra
1       SIMPLE          entity                  ALL     NULL            NULL            NULL    NULL                            429     100.00          Using where; Using temporary; Using filesort
1       SIMPLE          individual_donation     ref     entityno        entityno        3       dakotask_ds1.entity.recordno    3       100.00
1       SIMPLE          season_tickets          ref     entityno        entityno        3       dakotask_ds1.entity.recordno    2       100.00
1       SIMPLE          single_tickets          ref     entityno        entityno        3       dakotask_ds1.entity.recordno    1       100.00          Using where

【讨论】:

  • 是的,这就行了。当查询计划程序无法在所需列上找到任何索引时,它很可能会假设最坏的情况。在entitynorecordno 上添加索引应该可以解决问题。当查询计划器很愚蠢时,运行ANALYZE TABLE 也是明智之举。
  • @Charles ANALYZE TABLE 完全修复了我无缘无故吓坏了的加入。非常感谢。
【解决方案2】:

尝试在执行主查询之前作为查询运行

mysql_query("SET SQL_BIG_SELECTS=1");

【讨论】:

    【解决方案3】:

    你可以试试:

    $query = "SELECT ... ";
    
    mysqli_query($databaseConnection, "SET OPTION SQL_BIG_SELECTS=1");
    
    $results = mysqli_query($databaseConnection, $query);
    

    【讨论】:

      猜你喜欢
      • 2010-10-30
      • 1970-01-01
      • 1970-01-01
      • 2010-11-01
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多