Проблема со скоростью запросов SQL - PullRequest
2 голосов
/ 10 августа 2011

Я боролся с запросом MySQL, который выполняется очень медленно.Я надеюсь, что некоторые из вас смогут дать мне несколько советов о том, как увеличить скорость этого запроса.

Это структура таблицы:

+---------------+------------+------+-----+-------------------+----------------+
| Field         | Type       | Null | Key | Default           | Extra          |
+---------------+------------+------+-----+-------------------+----------------+
| id            | int(11)    | NO   | PRI | NULL              | auto_increment |
| MedlemsID     | int(11)    | NO   | MUL | NULL              |                |
| Medlemsnummer | int(11)    | NO   |     | NULL              |                |
| Handling      | tinyint(1) | NO   |     | NULL              |                |
| KlubID        | int(11)    | NO   |     | NULL              |                |
| Klubtype      | varchar(5) | NO   |     | NULL              |                |
| Tidspunkt     | timestamp  | NO   | MUL | CURRENT_TIMESTAMP |                |
| Køn           | int(1)     | NO   |     | NULL              |                |
+---------------+------------+------+-----+-------------------+----------------+
8 rows in set (0.00 sec)

Это запрос:

        SELECT * FROM ( 
                    SELECT * 
                        FROM Handlinger 
                        AS a 
                        WHERE date(Tidspunkt) = curdate() 
                        AND Tidspunkt = ( 
                            SELECT max(Tidspunkt) 
                            FROM Handlinger 
                            AS b 
                            WHERE a.MedlemsID = b.MedlemsID 
                            AND a.Klubtype = b.Klubtype 
                            ) 
                            ) 
                            AS c 
                            WHERE Handling=1 
                            AND KlubID=1 
                            ORDER BY Medlemsnummer ASC

И вот результат:

+-------+-----------+---------------+----------+--------+----------+---------------------+-------+
| id    | MedlemsID | Medlemsnummer | Handling | KlubID | Klubtype | Tidspunkt           | Køn   |
+-------+-----------+---------------+----------+--------+----------+---------------------+-------+
| 24743 |       613 |            10 | 1        |      1 | UK       | 2011-08-10 12:14:10 | Pige  |
| 24733 |       572 |            11 | 1        |      1 | UK       | 2011-08-10 10:45:00 | Pige  |
| 24731 |       705 |            13 | 1        |      1 | FK       | 2011-08-10 10:31:35 | Dreng |
| 24740 |       409 |            51 | 1        |      1 | FK       | 2011-08-10 11:48:19 | Dreng |
| 24757 |       443 |            88 | 1        |      1 | FK       | 2011-08-10 15:01:43 | Dreng |
| 24730 |       723 |            89 | 1        |      1 | FK       | 2011-08-10 10:30:13 | Dreng |
| 24749 |       465 |           110 | 1        |      1 | FK       | 2011-08-10 13:29:40 | Dreng |
| 24720 |       483 |           129 | 1        |      1 | FK       | 2011-08-10 10:03:43 | Dreng |
| 24725 |       748 |           181 | 1        |      1 | FK       | 2011-08-10 10:12:11 | Dreng |
| 24748 |       540 |           207 | 1        |      1 | FK       | 2011-08-10 13:26:54 | Dreng |
+-------+-----------+---------------+----------+--------+----------+---------------------+-------+
10 rows in set (2.95 sec)

Я заранее благодарю вас за вашу помощь.

РЕДАКТИРОВАТЬ описание:

Само приложение работает как система регистрации для членов клуба.Каждый раз, когда член входит в систему или выходит из нее, он будет зарегистрирован в БД.Чтобы приложение было полезным, оно должно показывать, кто в сети в любое время суток.Таким образом, мой запрос получает все логины за день, и если последним действием является логин, то оно будет выведено в приложение.Все это работает как очарование, но это не так удобно для пользователя, если им приходится ждать несколько секунд, чтобы увидеть, кто в сети, а кто нет.

Надеюсь, это немного прояснит мою цель.:)

Ответы [ 4 ]

1 голос
/ 11 августа 2011

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

дата (TidSpunkt), Обработка, KlubID, MedlemsID

Затем попробуйте следующее ... Так как в таблице используется автоинкремент, наибольшее число будет означать самую последнюю дату ... Итак, мы можем получить максимальный идентификатор для MedlemsID, ​​чтобы обеспечить более быстрое объединение только тех, которые право

Select STRAIGHT_JOIN
      H1.*
   from 
      ( select 
              H2.MedlemsID, 
              max( H2.ID ) LastID
           from 
              Handlinger H2
           where
                  date( H2.Tidspunkt ) = curdate()
              AND H2.Handling = 1
              AND H2.KlubID = 1
           group by 
              H2.MedlemsID ) PreQuery
      JOIN Handlinger H1
         On PreQuery.LastID = H1.ID
   order by 
      H1.Medlemsnummer ASC
1 голос
/ 10 августа 2011

Вы проиндексировали свою таблицу?

Если нет, вы должны создать два индекса:

  • один на MedlemsID
  • и другой по клубтипу

Попробуйте сначала только на medlemsID, ​​уже должно быть намного лучше.

0 голосов
/ 11 августа 2011

Попробуй это. Коррелированные подзапросы всегда были довольно дорогостоящими. Вам, вероятно, понадобится ключ, используя 3 поля Присоединения, чтобы сделать это быстро.

SELECT a.*
FROM Handlinger as a
JOIN (SELECT medlemsID, KlubType, max(Tidspunkt) as maxTidspunkt
        FROM Handlinger
        GROUP BY medlemsID, KlubType) as b
  ON a.MedlemsID = b.MedlemsID
    AND a.KlubType = b.KlubType
    AND a.Tidspunkt = b.maxTidspunkt
WHERE a.Handling = 1
  AND a.KlubID = 1
  AND a.Tidspunkt = curdate()
ORDER BY a.Medlemsnummer ASC
0 голосов
/ 10 августа 2011

Я не знаю, почему вы написали эти подзапросы:

            SELECT * 
                FROM Handlinger 
                AS a 
                WHERE date(Tidspunkt) = curdate() 
                AND Tidspunkt = ( 
                    SELECT max(Tidspunkt) 
                    FROM Handlinger 
                    AS b 
                    WHERE a.MedlemsID = b.MedlemsID 
                    AND a.Klubtype = b.Klubtype 
                    ) 

Обратите внимание: вы не используете индекс из-за этой фразы date(Tidspunkt). Попробуйте:

SELECT `a`.* FROM Handlinger AS `a`
INNER JOIN (
    SELECT `id` FROM Handlinger WHERE
        Tidspunkt >= CONCAT(LEFT(NOW(), 10), ' 00:00:00')
        AND Handling=1 
        AND KlubID=1 
) AS jnd USING (`id`)
ORDER BY `a`.Medlemsnummer ASC
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...