0

我得到了这个查询,但它真的很慢。

我想要这个查询: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 ;
4

1 回答 1

0

最大的问题是!=andnot in子句。如果你重写它以不使用这些功能,你会更好。

指导

概括

MySQL 可以优化所有三种方法来执行一种 NESTED LOOPS ANTI JOIN。

它将从 t_left 中获取每个值,并在 t_right.value 的索引中查找它。在索引命中或索引未命中的情况下,相应的谓词将立即分别返回 FALSE 或 TRUE,并且将立即做出是否从 t_left 返回行的决定,而无需检查 t_right 中的其他行。

但是,这三种方法会生成三种不同的计划,由三段不同的代码执行。执行 EXISTS 谓词的代码比执行 index_subquery 和优化为使用 Not exists 方法的 LEFT JOIN 的代码效率低约 30%。

这就是为什么在 MySQL 中搜索缺失值的最佳方法是使用 LEFT JOIN / IS NULL 或 NOT IN 而不是 NOT EXISTS。

于 2013-07-16T17:00:41.183 回答