最快的MySQL匹配方式和返回true和false

时间:2015-10-14 15:45:21

标签: php mysql

我有一系列搜索词。

$unprocessed=array("language1 word1", "language1 word2", "language1 word3");

$ unprocessed中的每个单词在名为“language1”的列中都有唯一的条目

如果找到,则返回行列“language2”,否则返回false。重要的是,如果找不到单词,则返回false。

1. $unprocessed=array("language1 word1", "language1 word2", "language1 word3");

2. MySQL Query (what is best way?)

3. $processed=array(false,"language2 word2","language2 word3");

是否可以在不循环查询的情况下执行此操作? 什么是最好的方法:使用WHERE =“word”,IN(“word”),LIKE =“word”或其他什么?

2 个答案:

答案 0 :(得分:1)

  

$ unprocessed中的每个单词在名为" language1"

的列中都有一个唯一条目

这意味着你想要使用LIKE。您可以运行这样的单个查询,并返回一个包含所请求单词的列的单个元组:

SELECT MAX(IF(language1=':word1', 1, 0)) AS hasWord1,
       MAX(IF(language1=':word2', 1, 0)) AS hasWord2,
       MAX(IF(language1=':word3', 1, 0)) AS hasWord3
FROM table WHERE language1 IN (':word1',':word2',':word3');

这比三个单字查询更具性能,特别是如果您在language1上有索引。如果您需要语言表中的更多列(即不仅仅是单词,而且,例如,它的权重或其SVO状态或......),您最好为每个单词要求一个元组。但是在这种情况下,缺少单词将不会被返回(无论如何,你没有数据)。明智地使用LEFT JOIN加上第一个查询可以用来避免这种情况。

SELECT * FROM table WHERE language1 IN (':word1',':word2',':word3');

或     SELECT table2。* FROM表LEFT JOIN表AS table2 USING(primaryKey)         WHERE table.language1 IN(':word1',':word2',':word3');

您还可以使用二进制表示来获取一列以识别单词:

SELECT   MAX(IF(language1=':word1', 1, 0))
       + MAX(IF(language1=':word2', 2, 0))
       + MAX(IF(language1=':word3', 4, 0))
       AS wordMask, ...

或者,在JOIN的情况下,它足以获得索引:

SELECT   MAX(IF(language1=':word1', 1, 0)
       + MAX(IF(language1=':word2', 2, 0)
       + MAX(IF(language1=':word3', 3, 0)
       AS wordIndex, ...

要构建查询,可以使用PHP foreach循环。

如果是简单的翻译表:

SELECT MAX(IF(language1=':word1', language2, ':word1')) AS word1,
       MAX(IF(language1=':word2', language2, ':word2')) AS word2,
       MAX(IF(language1=':word3', language2, ':word3')) AS word3,
FROM table WHERE language1 IN (':word1',':word2',':word3');

将返回单词 n ,其中包含原始单词或"翻译的"来自language2专栏的词:

 select MAX(IF(language1='computer', language2, '-')) AS hasWord1, MAX(IF(language1='ouijamaflip', language2, '-')) AS hasWord2 FROM tbl WHERE language1 IN ('computer', 'ouijmaflip');
+------------+----------+
| hasWord1   | hasWord2 |
+------------+----------+
| ordinateur | -        |
+------------+----------+

您还可以使用语言优先级,再次在PHP中构建:

SELECT 
    MAX(IF (language1=':word1',
        COALESCE(language2, language3, language4, ':default1')))
        AS word1,

您可以将$default设置为$word,或者"?{$word}?"或类似。

$words = array( 'computer', 'bytes', 'processor' /*, 'other'... */);
$langs = array( 'language2', 'language3' /*, 'language4', ... */ );

$rets  = array();
$whrs  = array();
$defs  = array();
foreach ($words as $ndx => $word) {
    $rets[] = "COALESCE(IF (language1 = ':word{$ndx}', COALESCE("
            . implode(", ", $langs) . "), ':default{$ndx}')) AS word{$ndx}";
    $whrs[] = "':word{$ndx}'";
    $defs[] = "MISSING_{$word}";

}
$SQL = "SELECT " 
   . implode(", ", $rets) // All IFs
   . " FROM table WHERE language1 IN("
   . implode(", ", $whrs) . ");"; // All WHEREs

这将返回一个查询,例如:

SELECT 
    COALESCE(
        IF (language1='computer',
            COALESCE(language2, language3),
            'MISSING_computer')
    ) AS word1,
    COALESCE(
        IF(language1='bytes', 
            COALESCE(language2, language3),
            'MISSING_bytes')
    ) AS word2,
    COALESCE(
        IF(language1='processor',
           COALESCE(language2, language3),
           'MISSING_processor')
    ) AS word3
 FROM tbl
 WHERE language1 IN ('computer', 'bytes', 'processor');

最后,用这个tbl:

+-----------+------------+-----------+
| language1 | language2  | language3 |
+-----------+------------+-----------+
| computer  | ordinateur | NULL      |
| bytes     | NULL       | ottetti   |
+-----------+------------+-----------+

它会返回

+------------+---------+-------------------+
| word1      | word2   | word3             |
+------------+---------+-------------------+
| ordinateur | ottetti | MISSING_processor |
+------------+---------+-------------------+

ordinateur 将取自第一语言,因为它在那里, ottetti 来自第二语言,因为第一语言是NULL,而处理器返回错误,因为它完全丢失或所有相关列都为NULL。您可以通过添加" language1"来区分这些情况。 (或诸如“EMPTY ROW'”之类的字符串)作为最不重要的语言。

答案 1 :(得分:0)

据我所知,根据评论你不能只用MySQL来做,你需要PHP来处理它。

假设你正在使用pdo ..这个伪代码应该为你做

function whatever($unprocessed){
    global $db;
    $processed = array();
    foreach($unprocessed as $u){
        $q = $db->prepare("SELECT * FROM language1 WHERE word = :wrd");
        $q->execute(array(":wrd"=>$u));
        $processed[] = $q->rowCount() ? $q->fetchColumn() : false;
    }
    return $processed;
}