优化sql join查询,比较查询效果

时间:2011-05-27 16:41:12

标签: mysql sql

我是一名学生正在为我的学院的moodle cms(课程管理系统)工作。我必须为我的模块编写一些连接查询。我不能对表结构进行更改,它们几乎是一成不变的(我没有制作它们,它们是给我的)。

我没有为大型数据库编写查询的经验。我已经创建了我的模块的工作原型,现在我正在尝试组织代码/优化查询等。

任务:

| id     | task    |
--------------------
| 1      | task1   |
| 2      | task3   |
| 3      | task3   |
| 4      | task4   | 
| ...    | ...     |

资产:

| id     | asset   |
--------------------
| 1      | task1   |
| 2      | task3   |
| 3      | task3   |
| 4      | task4   |
| ...    |   ...   |

TaskAsset:

| id     | taskid  | assetid  | coefficient   |
-----------------------------------------------
| 1      |    2    |     33   | coefficient1  |
| 2      |    5    |     35   | coefficient2  |
| 3      |    6    |     36   | coefficient3  |
| 4      |    8    |     37   | coefficient4  |
| 5      |   ...   |    ...   |      ...      |
$query = "SELECT TaskAsset.id as id, Assets.asset AS asset, Tasks.task AS task
, coefficient
FROM Tasks, Assets, Taskasset
WHERE Taskasset.taskid= Tasks.id AND TaskAsset.assetid = Assets.id";

$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result))
{
  echo $row['id']." - ".$row['asset']." - ".$row['task'] . $row['coefficient'];
  echo "<br />";
}

问题:
1.)所以,如果表结构是这样的,我的查询是否有效? 如果他们是,如果我必须加入更多的表,一个简单的连接仍然有效吗?像4或5?

2.。)如何评价查询的有效性?在phpmyadmin中,我可以看到查询运行所花费的时间。我从来没有用过任何其他东西,因为我的表记录很少,所以没关系。

4 个答案:

答案 0 :(得分:7)

我唯一要做的就是明确指定连接。

$query = "SELECT ta.id as id, a.asset AS asset, t.task AS task
, coefficient
FROM TaskAsset ta
JOIN Tasks t ON ta.taskId = t.id
JOIN Assets a ON ta.assetId = a.id";

这也是一样,但我个人更喜欢它。也就是说,您应该尝试在查询中运行EXPLAIN。那是你会看到压力点的地方。

答案 1 :(得分:3)

从最优性的角度来看,您的查询很好,假设索引存在于表的id字段中。使用正确的索引,您可以加入更多表,性能仍然很好。

您应该尝试熟悉ANSI连接语法 - 因为这比旧的FROM x, y, z ...样式连接更容易阅读 - 并且更难以出错!

答案 2 :(得分:2)

此查询适用于您想要的结果。

TaskAssets是一个映射表,用于通过外键将Task和Asset的列连接在一起。您需要查看结果集的所有三个表中的列,这是完成此操作的最有效方法。

答案 3 :(得分:2)

可能比查询更重要的是表格中的索引

你在做什么

SELECT ta.id as id, a.asset AS asset, t.task AS task, coefficient
FROM TaskAsset ta
JOIN Tasks t ON ta.taskId = t.id      <-- equi join here
JOIN Assets a ON ta.assetId = a.id    <-- another equi join.

此查询有两个equi连接。

  1. 始终为equi-join中涉及的字段分配索引。
  2. 考虑为where子句中涉及的字段分配索引(此查询除此之外没有任何内容)
  3. 强烈考虑在group by子句
  4. 中使用的字段上添加索引