Может ли кто-нибудь помочь мне с оптимизацией моего запроса, чтобы сократить время результата? - PullRequest
0 голосов
/ 18 января 2019

Я написал MYSQL-запрос без особых знаний в этой области, но, поскольку размер моей базы данных увеличился, я считаю, что результаты возвращаются слишком долго. Я могу понять, почему, но я не могу понять, как лучше сгруппировать мой запрос, чтобы MYSQL не просматривал всю базу данных, чтобы вернуть результаты. Я знаю, что есть гораздо более эффективный способ сделать это, но я не могу понять, как это сделать. Если я удалю оператор ORDER BY, результаты будут возвращены менее чем за четверть времени. Теперь, когда таблица имеет 180 000 записей (членов), для возврата результатов требуется около 4 секунд.

SELECT members.mem_id, members.username, members.online, 
       members.dob, members.regdate, members.sex, 
       members.mem_type, members.aboutme, 
       geo_cities.name AS city, 
       geo_countries.name AS country, photos.photo_path
        FROM members
        LEFT JOIN geo_cities
        ON members.cty_id=geo_cities.cty_id
        LEFT OUTER JOIN geo_countries
        ON geo_cities.con_id=geo_countries.con_id
        RIGHT OUTER JOIN photos
        ON members.mem_id=photos.mem_id
        WHERE (photos.main=1 
          AND photos.approved=1
          AND members.banned!="1"
          AND members.profile_photo="1"
          AND members.profile_essentials="1"
          AND members.profile_user="1")
        ORDER BY lastdate DESC
        LIMIT 12

1 Ответ

0 голосов
/ 18 января 2019

Похоже, вы хотите показать 12 последних участников, которые соответствуют определенным критериям.

Несколько вещей.

  1. Ваш RIGHT JOIN на photos на самом деле является обычным внутренним JOIN: его столбцы появляются в вашем предложении WHERE.
  2. Возможно, вам нужны составные индексы для таблиц members и photos.
  3. SELECT many columns FROM ... JOIN ... ORDER BY column... LIMIT 12 - пресловутый антипаттерн производительности: он создает сложный набор результатов, затем сортирует все, а затем отбрасывает почти все. Расточительное.
  4. У вас есть WHERE....members.banned != "1" Подобные фильтры неравенства делают работу SQL сложнее (== медленнее), чем равенства. Если вы можете изменить это на = "0" или что-то подобное, сделайте это.

(Я полагаю, ваш столбец lastdate находится в таблице members, но вы не сказали нам этого в своем вопросе.)

Так что попробуйте что-то вроде этого, чтобы найти двенадцать участников, которых вы хотите отобразить.

          SELECT members.mem_id
            FROM members
            JOIN photos ON members.mem_id=photos.mem_id
           WHERE photos.main=1 
             AND photos.approved=1
             AND members.banned!="1"
             AND members.profile_photo="1"
             AND members.profile_essentials="1"
             AND members.profile_user="1")
           ORDER BY lastdate DESC
           LIMIT 12

Это дает вам идентификаторы двенадцати членов, которых вы хотите. Используйте его в своем основном запросе.

    SELECT members.mem_id, members.username, members.online, 
           members.dob, members.regdate, members.sex, 
           members.mem_type, members.aboutme, 
           geo_cities.name AS city, 
           geo_countries.name AS country, photos.photo_path
      FROM members
      LEFT JOIN geo_cities    ON members.cty_id=geo_cities.cty_id
      LEFT JOIN geo_countries ON geo_cities.con_id=geo_countries.con_id
      JOIN photos ON members.mem_id=photos.mem_id
    WHERE members.mem_id IN (
          SELECT members.mem_id
            FROM members
            JOIN photos ON members.mem_id=photos.mem_id
           WHERE photos.main=1 
             AND photos.approved=1
             AND members.banned!="1"
             AND members.profile_photo="1"
             AND members.profile_essentials="1"
             AND members.profile_user="1")
           ORDER BY lastdate DESC
           LIMIT 12
         )
    ORDER BY lastdate DESC
    LIMIT 12

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

Затем создайте составной индекс для members(profile_photo, profile_essentials, profile_user, banned, lastdate). Этот составной индекс значительно ускорит ваше WHERE предложение.

Аналогично, создайте составной индекс на photos(mem_id, main, approved, photo_path).

Вещи всегда становятся захватывающими, когда базы данных начинают расти! Прочитайте онлайн-книгу Маркуса Винанда https://use -the-index-luke.com /

...