【问题标题】:MySQL - Best practice to cross two tablesMySQL - 跨两个表的最佳实践
【发布时间】:2012-05-16 20:12:30
【问题描述】:

我有两张桌子。每一个都填充了大约 50K 条记录。两者都有一个共同的领域。我想要公共字段匹配的两个表的记录。所以我使用下面的 SQL 代码。问题是查询现在已经运行了 20 分钟,但什么也没发生。我觉得很奇怪,它花了这么多时间。我想知道是否有更好的方法来实现我的目标。预先感谢您的回复。

我的 SQL 代码:

Select * from tableOne T1, tableTwo T2 
Where T1.name = T2.name

顺便说一句,我对 php 解决方案持开放态度(循环或其他更好的...)

【问题讨论】:

  • 我想你也可以向我们展示 2 个表的 ddl + 索引 :-)
  • 您的表可能没有正确索引。
  • 最佳实践是使用inner join,尽管这不会是这里失败的原因。为什么 MySQL 在标题上,而不是在标签上?您能否提供更多有关您如何使用它的背景信息?
  • 最佳实践是在询问此类问题时包含 EXPLAIN $your_query 的输出。 (并学习如何解释自己)。你如何加入这两个表与最佳实践无关(只要它是在数据库中完成的——但与你得到的结果有关)

标签: php mysql sql select


【解决方案1】:

两件事:

  1. 您需要确保两个表中的 name 列都有索引。否则查询将不得不扫描每个表的每一行以查找匹配项。

  2. 理想情况下,索引应该具有您要在查询中选择的“包含的列”。否则查询将无法完全使用索引,但必须返回表并为每一行手动提取其他列。这意味着您应该考虑在查询中仅选择您需要的列(而不是 *),并将这些列作为包含列添加到索引中。

【讨论】:

  • 你好。当我听到索引时,我会想到主键和唯一索引以避免重复。这就是我对索引的全部了解。你是在说同样的想法吗?我可以在 PHP My Admin 中设置它们吗?谢谢...
  • @Marc:索引有 4 种类型。 PRIMARY KEYUNIQUEINDEXFULLTEXT。在 phpMyAdmin 中查看表的结构时,单击字段旁边的“索引”按钮(看起来像黄色闪电),在本例中为“名称”。 INDEXes 用于帮助 MySQL 搜索/排序表。 dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html
  • 是的,只有一个 Index 是您想要的。它不是主键或唯一键,而纯粹是为了方便对其包含的列进行查询。
  • 所以我在我试图跨越的两个表之间的两个常见字段上添加一个索引?
  • 太棒了!!!这就成功了。在两个公共字段上放置索引后,我的查询已在几分之一秒内执行。非常感谢:)
【解决方案2】:

试试这个:

select *
from tableOne t1
inner join tableTwo t2 on t1.name = t2.name

虽然我怀疑这会有所作为,但尝试不会有什么坏处。不建议使用 from tableOne t1, tableTwo t2,因为你在隐式地做一个笛卡尔积!

【讨论】:

  • from tableOne T1, tableTwo T2 where T1.name = T2.nameINNER JOIN table2 t2 ON t1.name = t2.name 相同。
  • 是的,我知道,这就是为什么我说“尝试不会伤害”。我们需要更多上下文,因为挂起 50k 条记录是荒谬的。
【解决方案3】:

我认为最好使用Join

类似这样的:

SELECT *
FROM tableOne
INNER JOIN TableTwo
ON tableOne.name=TableTwo.name

【讨论】:

  • 你好,埃里克。我正在做的事情和使用内部连接在性能方面似乎几乎相同......
  • 我不认为这么长时间执行查询是有效的。您是通过 PHP 尝试还是在服务器上运行查询?如果是通过 PHP 可能出了点问题...
  • from tableOne T1, tableTwo T2 where T1.name = T2.nameINNER JOIN table2 t2 ON t1.name = t2.name 相同。
【解决方案4】:

应该是一个内部连接,以从两个表中获取连接名称的行。

SELECT t1.*, t2.* FROM table1 t1 INNER JOIN table2 t2 ON t1.name = t2.name

【讨论】:

  • from tableOne T1, tableTwo T2 where T1.name = T2.nameINNER JOIN table2 t2 ON t1.name = t2.name 相同。
  • 那就是索引问题。根据另一位评论者的建议,添加一个 INDEX 来命名。您的语法不是 ANSI SQL。
  • 我认为 FROM table1,table2 是 MySQL 特定的扩展。
  • 随着您职业生涯的发展(如果这确实是您的职业),那么您将不可避免地遇到各种数据库供应商(postgres、sql server、oracle),您将获得最好的学习标准SQL 语法。相信我。在那里,做了很多年。
  • 此外,最好加入数字索引,即使向 varchar 添加索引会加快速度。您应该将字符串集标准化为 [ 1 |福,2 | Bar ] 然后在您的 2 个表中使用该表上的索引。如果您确实需要使用字符串表示形式进行连接,那么您可以将此元表连接到混合中并将其添加到 WHERE。无论如何...
【解决方案5】:

MySQL 内部连接——你在那里发生的事情——非常有效。 50K 条记录根本不算多,即使对于有几百万条记录的一对表来说,20 分钟也长得离谱。尝试重新启动查询,或者只是重新启动整个 Web 服务器。查询本身是否正常(尽管最好从每个表中准确指定您想要的列,即使您想要除一个之外的每一列)。如果没有索引,添加索引也是一个好主意。

【讨论】:

    【解决方案6】:

    您的表的存储引擎是什么?如果是 InnoDB,你需要在这两个表之间设置一个外键——这肯定会解决你的性能问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-30
      相关资源
      最近更新 更多