2011-05-27 105 views
1

我是一名学生,工作于我大学的moodle cms(课程管理系统)模块。我必须为我的模块编写一些连接查询。我无法修改桌子的结构,它们几乎都是石制的(我没有制作它们,它们都是给我的)。优化sql连接查询,比较查询效率

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

任务:

 
| 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 />"; 
} 

Questio ns:
1)那么,如果表结构是这样的,我的查询是否有效? 如果他们是,如果我不得不加入更多的表,那么简单的连接仍然有效吗?喜欢4还是5?

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

+0

请不要在连接中使用那些隐含的隐含。它烧我的眼球。 – Johan 2011-05-27 17:17:29

+0

我用你的TaskAsset表把我的头发用代理id键 - 建议:engine = innodb,主键(taskid,assetid) – 2011-05-27 18:01:31

+0

多个用户可以有相同的taskid和assetid组合的记录,这意味着需要id 。否则,我会用你的建议。以前不知道。 – afaf12 2011-05-27 18:20:49

回答

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。这是你会看到压力点的地方。

3

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

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

2

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

TaskAssets是一个映射表,旨在通过外键将任务和资产的列连接在一起。您需要从结果集的所有三个表中查看列,因此这是完成它的最有效方式。

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. 

此查询有两个相等连接。

  1. 始终为涉及等同连接的字段分配索引。
  2. 考虑在参与where条款字段分配索引(这个查询没有任何但那是题外话)
  3. 认真考虑把一个指数在group by从句使用的字段
+0

现在这是我没有足够的重视。谢谢。 – afaf12 2011-05-27 17:49:12