SQL оставил выполнения запроса соединения ОЧЕНЬ медленными

Для любого значительного дизайна будет нужна некоторая абстракция для базы данных, только для обработки несоответствия импеданса. Но самый простой первый шаг (и достаточный для большинства случаев) я ожидал бы, будет DAL, не тяжелый ORM. Ваши единственные опции не являются опциями в концах спектра.

<час>

РЕДАКТИРОВАНИЕ в ответ на комментарий, запрашивающий меня описать, как я отличаю DAL от ORM:

А DAL - то, что Вы пишете себе, возможно, начинающий с класса, который просто инкапсулирует таблицу и отображает ее поля на свойства. ORM является кодом, который Вы не пишете или механизмы абстракции, выведенные из других свойств Вашей схемы DBMS, главным образом PKs и FKs. (Это - то, где Вы узнаете, начинают ли автоматические абстракции становиться текучими или нет. Я предпочитаю сообщать им намеренно, но который может просто быть моим персональным предпочтением).

9
задан OMG Ponies 15 October 2009 в 23:53
поделиться

5 ответов

Скорее всего, вам понадобится индекс на

responses.questionID
responses.username 

Без индекса поиск по 30k строкам всегда будет медленным.

11
ответ дан 4 December 2019 в 10:04
поделиться

Вот другой подход к запросу, который мог бы быть быстрее:

SELECT q.id
FROM questions q
WHERE q.id NOT IN (
    SELECT r.questionID
    FROM responses r
    WHERE r.username = 'someuser'
)

Убедитесь, что есть индекс на r.username , и это должно быть довольно быстро.

] Вышеупомянутые ответы вернут все оставшиеся без ответа вопросы. Чтобы выбрать случайный вариант, вы можете использовать неэффективный (но простой) ORDER BY RAND () LIMIT 1 или использовать метод, предложенный Томом Лейсом.

4
ответ дан 4 December 2019 в 10:04
поделиться

Проблема, вероятно, не в соединении, оно почти наверняка сортирует 30 тыс. Строк по порядку rand ()

3
ответ дан 4 December 2019 в 10:04
поделиться

См .: Не упорядочивать по rand

Он предлагает (замените кавычки в этом примере вашим запросом)

SELECT COUNT(*) AS cnt FROM quotes

-- generate random number between 0 and cnt-1 in your programming language and run 
-- the query:

SELECT quote FROM quotes LIMIT $generated_number, 1

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

3
ответ дан 4 December 2019 в 10:04
поделиться

Уверен ли OP даже, что исходный запрос возвращает правильный набор результатов?

Я предполагаю, что предложение «AND response.username = 'someuser'» было добавлено в спецификацию соединения с намерением, что соединение будет затем сгенерируйте пустые столбцы правых сторон только для идентификаторов, на которые не ответил какой-то пользователь.

Мой вопрос: не будет ли это соединение генерировать пустые столбцы правых сторон для каждого question.id, на который не ответили все пользователи? Левое соединение работает таким образом, что «Если какая-либо строка из целевой таблицы не соответствует выражению соединения, то для всех ссылок столбцов на целевую таблицу в списке столбцов SELECT генерируются значения NULL».

В любом случае, nickf's предложение мне нравится.

0
ответ дан 4 December 2019 в 10:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: