MySQL查询性能优化

标签 mysql performance

我的数据库中有一个字典,其中有超过百万条记录和这个简单的选择

select * from Word where languageId = 'en' order by rand() limit 1

随机选择一个词。

问题是这个请求持续了 3-4 秒,这很长,因为我必须重复多次。

有没有一种方法可以达到同样的目的,但速度要快得多?

编辑 - 表架构

wordId - integer, auto increment
languageId - varchar (FK), values like cs, en, de, ... 
word - varchar, word itself

数据结构示例

wordId   languageId   word
--------------------------
1        cs           abatyše
...
100000   cs           zip
100001   en           aardvark
...
etc

SQL

CREATE TABLE Language (
  languageId VARCHAR(20)  NOT NULL  ,
  name VARCHAR(255)  NULL    ,
PRIMARY KEY(languageId));

CREATE TABLE Word (
  wordId INTEGER UNSIGNED  NOT NULL   AUTO_INCREMENT,
  languageId VARCHAR(20)  NOT NULL  ,
  word VARCHAR(255)  NULL    ,
PRIMARY KEY(wordId)  ,
INDEX Word_FK_Language(languageId),
  FOREIGN KEY(languageId)
    REFERENCES Language(languageId)
      ON DELETE NO ACTION
      ON UPDATE NO ACTION);

最佳答案

如果你有一个 IDs 列并且元素之间的间隙不是很大(没有删除太多元素,否则一些元素会被更频繁地选择)然后尝试这个查询

SELECT * FROM `table` 
   WHERE id >= 
      (SELECT FLOOR( MAX(id) * RAND()) FROM `table` WHERE languageId = 'en' ) 
   AND languageId = 'en'
   ORDER BY id LIMIT 1;

并在这里查看不同的示例 http://akinas.com/pages/en/blog/mysql_random_row/

ps:我刚刚意识到它只有在不需要 languageId 的情况下才能正常工作,否则相同 languageId 的 ID 之间的差距可能会很大。

已更新 试试这个,它可能会快几倍。我根据您的查询的执行时间检查了它..快了两倍..

SELECT d.* FROM
  (SELECT @rn:=0 ) r, 
  (SELECT FLOOR(count(*)*RAND()) as rnd FROM `Word` WHERE languageId = 'en') t,  
  (SELECT @rn:=@rn+1 as rn, `Word`.* FROM `Word` WHERE languageId = 'en' ) d 
WHERE d.rn >= t.rnd LIMIT 1

基本上它仍然会创建某种连续的 id,但不会按它们排序。

上次更新 这个可能会更快(取决于生成的随机数)

SELECT d.* FROM
  ( SELECT @rn:=@rn+1 as rn, w.*, t.rnd rnd FROM 
     (SELECT @rn:=0 ) r, 
     (SELECT FLOOR(count(*)*RAND()) rnd FROM `Word` WHERE languageId = 'en') t, 
     `Word` w 
   WHERE w.languageId = 'en' AND @rn<t.rnd
  ) d 
WHERE d.rn=d.rnd

关于MySQL查询性能优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9219060/

相关文章:

php - mysql : how to submit 2 sets of checkbox in two different column in a table

php - 带有 order by rand 函数的 where 语句不起作用

java - hibernate 所需的 C3P0 设置是什么?

javascript - IE10+11 : onscroll & transform laggy performance

c - 32位浮点除法并没有我想象的那么慢

MySQL 常量字符串的最小 CHAR 存储

mysql - 查询可以获取玩家姓名(如果不为空)

sql - MySQL MyISAM 表性能问题重温

mysql - 使用 like vs group by 聚合函数的 SQL 查询 - 性能

c - 哪个更快更好?这种比较方法是真的吗?