Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 优化MySQL数据库的方法_Php_Mysql_Database_Optimization_Database Design - Fatal编程技术网

Php 优化MySQL数据库的方法

Php 优化MySQL数据库的方法,php,mysql,database,optimization,database-design,Php,Mysql,Database,Optimization,Database Design,我有一个MySQL数据库,包含标准英文字母表中的所有单词,我正在使用它创建一个简单的拼字生成器。数据库分为26个表:字母表中每个字母对应一个表。每个表包含两列: “Word”列:此列是主键,类型为char(12),不接受空值 “长度”列:此列包含无符号tinyint值,不接受空值 在我的应用程序中,用户在文本框中输入任意数量的字母(指示它们的分幅),我使用以下代码查询数据库: // this is looped over 26 times, and $char is a letter bet

我有一个MySQL数据库,包含标准英文字母表中的所有单词,我正在使用它创建一个简单的拼字生成器。数据库分为26个表:字母表中每个字母对应一个表。每个表包含两列:

  • “Word”列:此列是主键,类型为char(12),不接受空值
  • “长度”列:此列包含无符号tinyint值,不接受空值
在我的应用程序中,用户在文本框中输入任意数量的字母(指示它们的分幅),我使用以下代码查询数据库:

// this is looped over 26 times, and $char is a letter between 'A' and 'Z'
// check if the user entered in character $char or a blank tile (signified by ? in app)
// this check prevents me from having to query useless tables
if (in_array($char, $lettersArray) || $blanks)
{
    // if so, select all words that have a length that's possible to make
    $query = 'SELECT Word FROM '.$char.'Words WHERE Length <= '.strlen($letters);
    $result = $db->query($query);
    $num_results = $result->num_rows;

    for ($j = 0; $j < $num_results; $j++)
    {
        // determine if it's possible to create word based on letters input
        // if so, perform appropriate code
    }
}
//循环了26次,$char是“a”和“Z”之间的字母
//检查用户是否输入字符$char或空白磁贴(由应用程序中的?表示)
//这个检查使我不必查询无用的表
if(在_数组($char,$lettersArray)| |$blanks中)
{
//如果是,请选择所有长度可能为的单词

$query='SELECT Word FROM'.$char.'Word WHERE Length听起来您需要了解。如果您在数据库中创建索引,即使所有数据都在一个表中,也不会查询“无用的字母”

不过,您应该提供更多信息,如果从mysql控制台运行查询,返回结果需要多长时间,将结果从数据库移动到PHP引擎需要多长时间。例如,您可能会在运行每个查询时返回一个100兆的结果集,如果是这样,请将结果限制在first或一些可能的结果


看看要返回多少数据,手动在控制台中运行一个查询,看看有多少记录被返回。如果数字高,数据将需要更长的时间传递给PHP,但是这也意味着你的代码必须迭代更多的结果。你可能会考虑放弃< <代码> < <代码> >找到第一个可以接受的单词后进行操作。如果至少有一个单词是可能的,则在放置另一个字母之前不要再次检查。

我知道这个问题是关于优化数据库的,但如果我这样做,我只会从数据库中读取一次单词,初始化一些数据结构并搜索该结构,而不是c连续查询数据库


如果这完全不相关,很抱歉。

我认为性能问题并不真正在于数据库。数据存储的结构将对算法的性能产生最显著的影响

解决这个问题的一个相当容易理解的方法是将问题处理为字谜。你可以按字母顺序排列每个单词中的所有字母,并将其存储为一列,列上有索引

word      dorw
--------  -------
DALE      ADEL
LEAD      ADEL
LED       DEL
HELLO     EHLLO
HELP      EHLP
然后,给定一组字母,您可以查询数据库中所有匹配的字谜。只需按传入字母的字母顺序排列,然后运行查询

SELECT word FROM dictionary WHERE dorw = 'AERT'

RATE
TARE
TEAR
然后,您可以查询字母的子集:

SELECT word FROM dictionary WHERE dorw IN ('AER','AET','ART','ERT')
这种方法会让您首先返回最长的单词

这不是最有效的方法,但它是可行的

处理一个“空白”磁贴需要更多的工作,你需要用一个可能的字母来代替它,在一个查询中检查所有26个可能的字母

如果字母ABCD和空白瓦片,例如…

SELECT word FROM dictionary WHERE dorw IN ('AABCD','ABBCD', 'ABCCD'
 , 'ABCDD', 'ABCDE', 'ABCDE', 'ABCDF', ..., 'ABCDZ') 
当你开始处理子集时,这会变得更痛苦

(在纵横填字游戏和拼图游戏中,没有任何空白拼贴)

因此,这可能不是最合适的拼字算法


还有其他算法可能更有效,尤其是在首先返回较短的单词时

一种方法是构建一棵树

根节点是一个“零”字母单词。作为根节点的子节点,将是所有一个字母单词的节点。每个节点都将被标记是否表示有效单词。作为这些节点的子节点,您将拥有所有可能的三个字母单词,再次标记为是否有效

这将有很多节点。对于长度不超过12个字母的单词,总的可能空间为
1+26+26**2+26**3+26**4+…

但是你不需要存储每个可能的节点,你只需要存储那些产生一个有效单词的分支。你不会在->Z->Z或->X->Q下面有分支

但是,在->X->Y->L下会有一个分支,即使XYL不是一个单词,它也会是指向“木琴”的分支的开始


但这是一种树遍历算法,它有着本质上的不同。

一个表或一个并集比26个分隔查询快得多。长度也应该是索引的谢谢您提供有关索引的信息。我目前在“Word”列中有一个,但在“Length”列中没有但是,如果我将所有数据放在一个表中,为什么数据库不会查询无用的信息,我感到很困惑。例如,即使用户输入不允许任何“a”,它不会拉出所有以“a”开头的单词吗要创建的单词?另外,从MySQL控制台运行查询平均每个表需要0.0009秒,但我不确定如何测试将结果从数据库移动到PHP引擎需要多长时间。您应该在
where
子句中使用的字段中或在链接t中使用的列中拥有索引o其他表。这基本上告诉db确切的查找位置,而不必对所有数据行进行排序。如果您将所有数据放在一个表中,您可以添加一个字符,并在其上弹出一个索引。索引和长度将真正帮助db找到正确的数据行。