2011-05-27 107 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