性能—从mysql获取数据,大约需要436秒

q1qsirdb  于 2021-06-18  发布在  Mysql
关注(0)|答案(1)|浏览(327)

我是android开发者,对mysql没有太多经验。我在mysql数据库中有3个表。
第一个表:-usertable

+-------------+-------------+----------+----------------------+
| user_id     | name      |   image    |   joining_date       |
+-------------+-------------+----------+----------------------+
|         100 | King      | defualt.jpg | 2018-05-23 20:09:27 |
|         101 | Kochhar   | defualt.jpg | 2018-05-23 20:09:27 |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |

第二个表:-friendrequests

+-------------+-------------+----------+
| unique_id   | from_id     |   to_id  |
+-------------+-------------+----------+
|         1  | 100          | 101      |
|         2  | 200          | 110      |
| - - - - - - - - - - - - - - - - - - -|
| - - - - - - - - - - - - - - - - - - -|

第三桌:-朋友

+-------------+-------------+----------+
| unique_id   | from_id     |   to_id  |
+-------------+-------------+----------+
|         1  | 104          | 101      |
|         2  | 206          | 110      |
| - - - - - - - - - - - - - - - - - - -|
| - - - - - - - - - - - - - - - - - - -|

我想得到的用户名单谁不是我的朋友,而且我们还没有挂起朋友的要求。所以我试着跟着query:-

SELECT usertable.name,
       usertable.user_id,
       usertable.image
FROM   `UserTable` AS usertable
WHERE  usertable.user_id <> '100'
       AND (SELECT Count(*)
            FROM   friendrequests
            WHERE  ( to_id = '100'
                     AND from_id = usertable.user_id )
                    OR ( to_id = usertable.user_id
                         AND from_id = '100' )) = 0
       AND (SELECT Count(*)
            FROM   friends
            WHERE  to_id = usertable.user_id
                   AND from_id = '100'
                    OR to_id = '100'
                       AND from_id = usertable.user_id) = 0
ORDER  BY usertable.joining_date DESC
LIMIT  10

它正在工作,但需要436秒。写这个查询的正确方法是什么?

lo8azlld

lo8azlld1#

以下是其他方法:
1) 使用 NOT IN 您在上添加了一个条件 usertable.user_id 不应该在id列表中:这些id是表的所有id friendrequests 以及 friends 那些有 to_id 或者 from_id = 100.

SELECT 
  usertable.name,
  usertable.user_id,
  usertable.image
FROM `UserTable` AS usertable
WHERE usertable.user_id <> '100'
  AND usertable.user_id NOT IN 
    (SELECT from_id as user_id FROM friendrequests WHERE to_id = '100'
     UNION
     SELECT to_id as user_id FROM friendrequests WHERE from_id = '100'
     UNION
     SELECT from_id as user_id FROM friends WHERE to_id = '100'
     UNION
     SELECT to_id as user_id FROM friends WHERE from_id = '100')               
ORDER  BY usertable.joining_date DESC
LIMIT  10

根据rick james评论编辑,与无工会相同:

SELECT 
  usertable.name,
  usertable.user_id,
  usertable.image
FROM `UserTable` AS usertable
WHERE usertable.user_id <> '100'
  AND usertable.user_id NOT IN (SELECT from_id as user_id FROM friendrequests WHERE to_id = '100')
  AND usertable.user_id NOT IN (SELECT to_id as user_id FROM friendrequests WHERE from_id = '100')
  AND usertable.user_id NOT IN (SELECT from_id as user_id FROM friends WHERE to_id = '100')
  AND usertable.user_id NOT IN (SELECT to_id as user_id FROM friends WHERE from_id = '100')               
ORDER  BY usertable.joining_date DESC
LIMIT  10

2) 使用 LEFT JOIN 我看到了这个答案,试着用同样的逻辑:你做一些 LEFT JOIN 并添加一个条件,其中这些连接返回空值

SELECT 
  usertable.name,
  usertable.user_id,
  usertable.image
FROM `UserTable` AS usertable
LEFT JOIN friendrequests as FRa on FRa.from_id = usertable_user_id
LEFT JOIN friendrequests as FRb on FRb.to_id   = usertable_user_id
LEFT JOIN friends        as Fa  on Fa.from_id  = usertable_user_id
LEFT JOIN friends        as Fb  on Fb.to_id    = usertable_user_id
WHERE usertable.user_id <> '100' 
  AND FRa.from_id IS NULL
  AND FRb.to_id IS NULL
  AND Fa.from_id IS NULL
  AND Fb.to_id IS NULL

3) 使用 NOT EXISTS ```
SELECT
usertable.name,
usertable.user_id,
usertable.image
FROM UserTable AS usertable
WHERE usertable.user_id <> '100'
AND NOT EXISTS (SELECT from_id as user_id FROM friendrequests WHERE to_id = '100')
AND NOT EXISTS (SELECT to_id as user_id FROM friendrequests WHERE from_id = '100')
AND NOT EXISTS (SELECT from_id as user_id FROM friends WHERE to_id = '100')
AND NOT EXISTS (SELECT to_id as user_id FROM friends WHERE from_id = '100')
ORDER BY usertable.joining_date DESC
LIMIT 10

抱歉,由于没有样本数据或sql fiddle来测试这些查询,我无法告诉您它是否返回您想要的结果,或者它是否真的更快。。。
编辑:这个网页是从2009年,所以结果有变化,因为!我不会删除它,因为您仍然具有我以前使用的查询结构:
我建议您查看本页以了解这些查询之间的区别,并为您提供一些实现所需的想法:https://explainextended.com/2009/09/18/not-in-vs-not-exists-vs-left-join-is-null-mysql/
本页提出了第三种方法(使用 `NOT EXISTS` )但根据测试,这并不有效:
然而,这个查询的效率比前两个稍微低一点:它需要0.92秒。
这并没有造成太大的性能下降,但是,查询所需的时间要多27%。

相关问题