Объясните MySQL эффективность присоединения - PullRequest
0 голосов
/ 26 мая 2020

У меня есть несколько mySQL таблиц, которые отражают отношения между BlogPost, пользователем и взаимодействием между пользователем и BlogPost

Я написал запрос, чтобы получить все сообщения, с которыми пользователь не взаимодействовал . Этот запрос создается из EntityFramework

_dbContext.Post.Where(!p.UserPostInteractions.Any(u => u.User.IndexedProperty == "SomeSpecificString")

SQL

SELECT COUNT(*)
      FROM `Post` AS `p`
      WHERE ( NOT EXISTS (
          SELECT 1
          FROM `UserPostInteractions` AS `u`
          LEFT JOIN `Users` AS `u.User` ON `u`.`UserId` = `u.User`.`Id`
          WHERE (`u.User`.`IndexedPropertyOnUserTable` = 'SomeSpecificString') AND (`p`.`Id` = `u`.`PostId`)) )

Этот запрос выполняется в течение 3,8 секунды. Таблица объяснений выглядит следующим образом:

+---+--------------------+--------+-------+---------------------------------------------------------------+--------------------------------+-----+-------------------+------+--------------------------+
| 1 | PRIMARY            | p      | index |                                                               | IX_Post_ParentPostId           |   5 |                   | 7261 | Using where; Using index |
| 2 | DEPENDENT SUBQUERY | u.User | ref   | PRIMARY,IX_Users_IndexedProperty                              | IX_Users_IndexedProperty       | 383 | const             |    1 | Using where; Using index |
| 2 | DEPENDENT SUBQUERY | u      | ref   | IX_UserPostInteractions_PostId,IX_UserPostInteractions_UserId | IX_UserPostInteractions_UserId |   5 | db-name.u.User.Id |   17 | Using where              |
+---+--------------------+--------+-------+---------------------------------------------------------------+--------------------------------+-----+-------------------+------+--------------------------+

Я попытался изменить его на

SELECT COUNT(*)
      FROM `Post` AS `p`
      WHERE ( NOT EXISTS (
          SELECT 1
          FROM `UserPostInteractions` AS `u`
          LEFT JOIN `Users` AS `u.User` ON `u`.`UserId` = `u.User`.`Id`
          WHERE (`u.User`.`Id` = 'usingIdInstead') AND (`p`.`Id` = `u`.`PostId`)) )

Этот запрос выполняется в течение 0,6 секунды

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

1 Ответ

1 голос
/ 26 мая 2020

Вот еще один способ сказать то же самое:

SELECT COUNT(*)
  FROM post p
  LEFT
  JOIN (
      SELECT up.postid
      FROM userpostinteractions up
      JOIN users u
      ON up.userid = u.id
      WHERE u.indexedpropertyonusertable = 'SomeSpecificString' 
    ) x
      ON p.id = x.postid
WHERE x.postid IS NULL
...