这几个表关联查询随机值,怎么写效率高?

MySql 码拜 4年前 (2016-02-20) 278次浏览
关系如下:userId关联多个TopicId(userTopic表),每个topicId对应多个dataId(datatopic表),每个dataId对应一条唯一的数据(data表),现在需要通过userId随机取出5条数据的详细内容,问一下怎么写效率高?原因是oder by rand效率很差,不敢用。
dataId是自增,但里面的数据并不一定连续,例如是1,2、3、4、7、9、12、54这样的。
表结构如下:

CREATE TABLE `userTopic` (
	`userTopicId` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT "表主键",
	`userId` BIGINT(20) NOT NULL COMMENT "用户id,与users表主键相同",
	`topicId` BIGINT(20) NOT NULL COMMENT "主题id,与topic表主键相同",
	PRIMARY KEY (`userTopicId`)
)
CREATE TABLE `datatopic` (
	`datatopicId` BIGINT(20) NOT NULL AUTO_INCREMENT,
	`dataId` BIGINT(20) NULL DEFAULT NULL,
	`topicId` BIGINT(20) NULL DEFAULT NULL,
	PRIMARY KEY (`datatopicId`)
)
CREATE TABLE `data` (
	`dataId` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT "数据编号",
	`dataName` VARCHAR(30) NOT NULL COMMENT "数据名称",
	`dataIntro` VARCHAR(200) NOT NULL COMMENT "数据简介",
	`keyword` VARCHAR(20) NOT NULL COMMENT "数据关键字",
	`pubDate` DATE NOT NULL COMMENT "数据发布日期",
	`updateDate` DATE NULL DEFAULT NULL COMMENT "数据更新日期",
	`pubState` INT(11) NOT NULL DEFAULT "0" COMMENT "发布状态:0:未审核,1:审核已通过,2:审核未通过",
	`userId` BIGINT(20) NOT NULL COMMENT "用户编号",
	`orgCode` VARCHAR(30) NOT NULL COMMENT "组织机构编号",
	`dataFormat` VARCHAR(100) NOT NULL COMMENT "数据格式,用于全文检索",
	`orgName` VARCHAR(30) NOT NULL COMMENT "组织机构名称",
	`dataTopic` VARCHAR(200) NOT NULL COMMENT "所述主题分类,用于全文检索",
	`recommend` INT(1) NOT NULL DEFAULT "0" COMMENT "推荐页面前面显示",
	`isDeleted` INT(1) NOT NULL DEFAULT "0" COMMENT "删除标记,0未删除1已删除",
	`c_date` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT "数据更新时间戳,无需处理",
	`downCount` INT(11) NOT NULL DEFAULT "0" COMMENT "下载次数",
	`evaluateCount` INT(11) NOT NULL DEFAULT "0" COMMENT "评论条数",
	PRIMARY KEY (`dataId`)
)
解决方案

5

需要通过userId随机取出5条数据的详细内容
你有相应的语句吗,先贴出来,然后再想 怎么样实现随机的5条数据

15

关于rand()优化,请参考文章:http://blog.csdn.net/tianlianchao1982/article/details/43528669

10

SET @mid = (SELECT 
    d.dataId, d.dataName, d.orgName
  FROM `data` d
  INNER JOIN datatopic dt
  ON d.dataId=dt.dataId
  INNER JOIN userTopic u
  ON u.topicId=dt.topicId
  WHERE u.userId=1234); -- 找出userid = 1234 的纪录数量
SELECT 
    d.dataId, d.dataName, d.orgName,
    FLOOR(1 + RAND() * @mid) AS rid
  FROM `data` d
  INNER JOIN datatopic dt
  ON d.dataId=dt.dataId
  INNER JOIN userTopic u
  ON u.topicId=dt.topicId
  WHERE u.userId=1234  
  ORDER BY rid LIMIT 0, 5

11

这么写, 不用排序了,应该还会快点,但是没法保证在生成的十个随机数中,能有5个是不重复的。假如纪录条数比较少,例如少于20条,这个时候,10个随机数,少于5个不重复的情况会很常见了。

SET @mid = (SELECT 
    d.dataId, d.dataName, d.orgName
  FROM `data` d
  INNER JOIN datatopic dt
  ON d.dataId=dt.dataId
  INNER JOIN userTopic u
  ON u.topicId=dt.topicId
  WHERE u.userId=1234); -- 找出userid = 1234 的纪录数量
SET @cnt = 0;
SELECT t.dataId, t.dataName, t.orgName 
FROM
(
  SELECT 
    d.dataId, d.dataName, d.orgName,
    (@cnt := @cnt + 1) AS rid
  FROM `data` d
  INNER JOIN datatopic dt
  ON d.dataId=dt.dataId
  INNER JOIN userTopic u
  ON u.topicId=dt.topicId
  WHERE u.userId=1234
) AS t
  WHERE rid IN 
  (
     FLOOR(1 + RAND() * @mid), FLOOR(1 + RAND() * @mid),
     FLOOR(1 + RAND() * @mid), FLOOR(1 + RAND() * @mid),
     FLOOR(1 + RAND() * @mid), FLOOR(1 + RAND() * @mid),
     FLOOR(1 + RAND() * @mid), FLOOR(1 + RAND() * @mid),
     FLOOR(1 + RAND() * @mid), FLOOR(1 + RAND() * @mid)  
  )    
  LIMIT 0, 5

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明这几个表关联查询随机值,怎么写效率高?
喜欢 (0)
[1034331897@qq.com]
分享 (0)