Оптимизация запроса на соединение SQL, сравнение эффективности запроса - PullRequest
1 голос
/ 27 мая 2011

Я студент, работающий над модулем для 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 ]

7 голосов
/ 27 мая 2011

Единственное, что я хотел бы сделать по-другому, это явно указать соединения.

$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 голосов
/ 27 мая 2011

Ваш запрос в порядке с точки зрения оптимальности, при условии, что в полях id таблиц присутствуют индексы.С правильными индексами вы можете объединять гораздо больше таблиц, и производительность все равно будет хорошей.

Вы должны попытаться ознакомиться с синтаксисом объединения ANSI - так как его гораздо легче читать, чем старый FROM x, y, z ... стиль присоединяется - и еще сложнее ошибиться!

2 голосов
/ 27 мая 2011

Что может быть даже более важным, чем запрос, это индексы в таблицах.

Вы выполняете

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
2 голосов
/ 27 мая 2011

Этот запрос подходит для нужных результатов.

TaskAssets - это таблица сопоставления, предназначенная для объединения столбцов Task и Asset вместе с помощью внешних ключей.Вам нужно просмотреть столбцы из всех трех таблиц для вашего набора результатов, так что это самый эффективный способ сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...