我的查询工作正常,但速度很慢。
我想要这个查询:1个随机(id,word,meaning)
和1个随机错误的任何其他单词含义。如何通过查询获得更好的性能?
$offset_result = mysql_query("SELECT FLOOR(RAND() * COUNT(*)) AS offset FROM words WHERE APPROVAL=1 AND PERIOD<".$_SESSION['statistics']['d']." OR ( PERIOD=".$_SESSION['statistics']['d']." AND WEEK<=".$_SESSION['statistics']['h'].")");
$offset_row = mysql_fetch_object($offset_result);
$offset = $offset_row->offset;
$words = mysql_query("SELECT ID,WORD,MEANING,
(SELECT MEANING FROM words WHERE ID!=w.ID AND APPROVAL=1 AND WORD!=w.WORD AND NOT FIND_IN_SET(w.MEANING, OTHER_MEANING) AND ID >= (SELECT FLOOR( MAX(ID) * RAND()) FROM words) ORDER BY ID LIMIT 1) AS INCORRECT
FROM words w
LIMIT $offset, 1");
这是表格布局
CREATE TABLE words (
ID int(11) NOT NULL AUTO_INCREMENT,
APPROVAL tinyint(1) NOT NULL DEFAULT '1',
WORD varchar(255) COLLATE utf8_turkish_ci NOT NULL,
MEANING varchar(255) COLLATE utf8_turkish_ci NOT NULL,
OTHER_MEANING varchar(255) COLLATE utf8_turkish_ci NOT NULL,
PERIOD tinyint(1) NOT NULL,
WEEK tinyint(2) NOT NULL,
PRIMARY KEY (ID),
KEY APPROVAL (APPROVAL) )
ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_turkish_ci AUTO_INCREMENT=769 ;
答案 0 :(得分:0)
最大的问题是!=
和not in
子句。如果你重写这个不使用这些功能,你会更好。
摘要
MySQL可以优化所有三种方法来做一种NESTED LOOPS ANTI JOIN。
它将从t_left中获取每个值并在索引中查找 t_right.value。如果索引命中或索引未命中,则 相应的谓词将立即返回FALSE或TRUE, 分别和从t_left返回行的决定 将立即进行,而不检查t_right中的其他行。
然而,这三种方法产生了三种不同的计划 由三段不同的代码执行。执行的代码 EXISTS谓词的执行效率比执行的约低30% index_subquery和LEFT JOIN已优化为使用Not exists方法。
这就是为什么在MySQL中搜索缺失值的最佳方法 LEFT JOIN / IS为NULL或NOT IN而不是NOT EXISTS。