Медленный MySQL оставил запрос соединения с базой данных среднего размера - PullRequest
1 голос
/ 03 марта 2012

У меня есть две основные таблицы:

CREATE TABLE IF NOT EXISTS `users` (
    `id` INT(32) NOT NULL auto_increment UNIQUE,
    `profile_type` INT(3),
    `date_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `last_login` DATETIME DEFAULT 0,
    `username` VARCHAR(255) NOT NULL,
    `password` VARCHAR(32) NOT NULL,
    PRIMARY KEY(`id`, `profile_type`)
);

+----------+
| count(*) |
+----------+
|     6455 |
+----------+


CREATE TABLE IF NOT EXISTS `client_dept` (
    `id` INT(32) NOT NULL auto_increment,
    `date_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `client_id` INT(32) NOT NULL,
    PRIMARY KEY (`id`, `client_id`)
);
+----------+
| count(*) |
+----------+
|     9729 |
+----------+

Для этого примера в таблице users, profile_type & 32 выбирает всех пользователей, настроенных с профилем клиента.

Я пытаюсь ускорить запросы к базе данных пользователей при выполнении полных поисков и списков. В настоящее время я пытаюсь получить только список имен пользователей клиента и количество (id) количества отделов, назначенных этому пользователю.

Вот запросы, которые я пробовал, и время их обработки:

SELECT users.username 
FROM users 
LEFT JOIN client_dept ON users.id = client_dept.client_id 
WHERE users.profile_type & 32 
GROUP BY users.id;

6020 строк в наборе (9,85 с)

SELECT users.username 
FROM users 
LEFT JOIN ( 
    SELECT client_id, id 
    FROM client_dept 
    GROUP BY client_id 
) AS dept ON users.id = dept.client_id;

6020 строк в наборе (2,27 с)

SELECT user.username 
FROM ( 
    SELECT username, id 
    FROM users WHERE profile_type & 32 
) AS user 
LEFT JOIN ( 
    SELECT client_id, id 
    FROM client_dept 
    GROUP BY client_id ) AS dept ON user.id = dept.client_id;

6020 строк в наборе (2,21 с)

Я смотрел на другие ресурсы, и люди, кажется, думают, что подзапросы замедляют SQL, но в этом случае они ускоряют его. Тем не менее, у меня есть только <10 000 пользователей, поэтому обработка не займет «секунд», особенно когда я могу запросить стандарт базы данных и получить обычный ответ <0,01 с. </p>

Есть что-то, что я явно делаю неправильно, или есть более эффективные методы для оптимизации запросов? Общие страницы, на которых это будет использоваться (и используется), выполняют LIMIT $ X, 20, с различным поиском, выполняемым с помощью HAVING, но меня беспокоит медленный запрос.

1 Ответ

0 голосов
/ 10 марта 2012

Ваш запрос просто странный.

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

   select u.username,c.c 

    from 
     (select count(*) as c,client_id from client_dept  group by client_id) as c
    left join 
      users as u 
      on u.id=c.client_id;

Для ускорения вы можете увеличить эту переменную в моем.conf

sort_buffer_size = 64M
join_buffer_size = 64M

Также вы должны проверить, что индекс для пользователей (id) существует - вероятно, он существует.

...