Mysql Sql高效的多表查询

Mysql Sql高效的多表查询,mysql,sql,database,database-design,Mysql,Sql,Database,Database Design,我有两个表tbl\u数据和tbl\u用户数据 id (int) (primary) names (varchar) dept_id (int) tbl\U数据的结构 id (int) (primary) names (varchar) dept_id (int) tbl\u用户数据的结构: id (int) (primary) user_id (int) names_id (int) tbl\u data.id和tbl\u user\u data.name\u id是外键 在这种情况下,我

我有两个表
tbl\u数据
tbl\u用户数据

id (int) (primary)
names (varchar)
dept_id (int)
tbl\U数据的结构

id (int) (primary)
names (varchar)
dept_id (int)
tbl\u用户数据的结构:

id (int) (primary)
user_id (int)
names_id (int)
tbl\u data.id
tbl\u user\u data.name\u id
是外键

在这种情况下,我必须从
tbl_数据
中选择25个随机条目,而这些条目之前没有提供给特定用户。因此,我创建了一个
tbl\u user\u data
,它将存储
user\u id
names\u id
(来自已经提供的
tbl\u data
)。 我有点困惑,如何代表这一点进行查询,或者有没有其他有效的方法

注意:
tbl_数据
有超过500万条条目

到目前为止,我已经写了这篇文章,但它似乎不正确

SELECT td.names, td.dept_id
FROM tbl_data AS td
LEFT JOIN tbl_user_data AS tud ON td.id = tud.names_id
WHERE tud.user_id !=2
ORDER BY RAND( ) LIMIT 25

在名称和用户id上创建索引。为什么用户id为varchar? 如果需要是varchar并且varchar很长,请在用户id上创建部分索引。
您可以使用EXPLAIN查看使用您的查询的索引。

由于您没有从tbl_user_数据中选择任何内容,因此可以使用exists:

SELECT td.names, td.dept_id
FROM tbl_data AS td
where exists (
    select 1
    from tbl_user_data AS tud 
    where td.id = tud.names_id
    and tud.user_id !=2
)
ORDER BY RAND( ) LIMIT 25
tbl_数据(id)和tbl_用户数据(名称、用户id)的索引将有所帮助。

两件事:

首先。。。您需要
左连接。。。。是空的
模式,用于挑选尚未提供的商品。您需要在ON子句中提到用户id才能使其正常工作

SELECT td.names, td.dept_id
  FROM tbl_data AS td 
  LEFT JOIN tbl_user_data AS tud    ON td.id = tud.names_id
                                   AND tud.user_id = 2
 WHERE tud.id IS NULL
 ORDER BY RAND( ) LIMIT 25
其次,
orderbyrand()LIMIT…
在一张大桌子上表现得非常差。它必须选择整个表,然后对其进行排序,然后放弃其中除25项之外的所有项。这是极大的浪费,永远不会有体面的表现

通过只对
id
值进行排序,然后使用它们获取其他信息,可以减少浪费

这将获得25个随机ID值

                 SELECT td.id
                   FROM tbl_data AS td 
                   LEFT JOIN tbl_user_data AS tud    ON td.id = tud.names_id
                                                    AND tud.user_id = 2
                  WHERE tud.id IS NULL
                  ORDER BY RAND( )
                  LIMIT 25
这将获取您的姓名和部门id值

  SELECT a.names, a.dept_id
    FROM tbl_data AS a
    JOIN (
                 SELECT td.id
                   FROM tbl_data AS td 
                   LEFT JOIN tbl_user_data AS tud    ON td.id = tud.names_id
                                                    AND tud.user_id = 2
                  WHERE tud.id IS NULL
                  ORDER BY RAND( )
                  LIMIT 25
         ) b ON a.id = b.id
但是,这仍然是浪费。您可能希望构建此tbl_数据表的随机版本,然后按顺序使用它。你可以每天重新随机分组一次,就像这样

 DROP TABLE tbl_data_random;
 INSERT INTO tbl_data_random FROM
 SELECT * 
   FROM tbl_data
  ORDER BY RAND()

这样,您就不会一次又一次地进行排序,只是为了丢弃结果。而是偶尔随机化一次。

加上mysql标记My bad。用户id也是int,我已经解决了这个问题。谢谢。从诺兰的电影《一旦一个想法占据了大脑,它几乎不可能被根除》中可以看出:)我一直坚持将数据随机化并保存在不同的表格中,但每天显示随机条目确实是个好主意。