使用大型数组或大型表的最佳方法

时间:2016-08-21 07:51:01

标签: php arrays

我有表arseh,有10,000,000条记录。

我需要从这张表中选择超过10,000个。

为了提高速度,我从数据库中选择所有记录并填写全局数组, 然后在全局数组中搜索

         Arseh Table
------------------------------
|BlockCode|ID|FromYear|ToYear|
-----------------------------
|01011001 |1 |1350    |1395  |
|01250110 |1 |1355    |1366  |
|01020201 |10|1395    |1395  |
$ListMyArseBooklet = array();

function myselectArsehPriceBooklet($Year, $BlockCode, $ID) {
    $Handler = new DB();
    global $ListMyArseBooklet;

    if (empty($ListMyArseBooklet)) {
        //select from data base all data to global variable 
        $table = "arseh";
        $fields = "*";
        $ListMyArseBooklet = $baseClass - > select($table, $fields);
        //====================== 
    }

    //search value in array
    foreach($ListMyArseBooklet as $key => $R) {
            if ($R["BlockCode"] == $BlockCode && $R["ID"] == $ID && $R["FromYear"] <= $Year && $R["ToYear"] >= $Year)
                return $R;
    }
    //=====================
}

我将此功能称为10,000以上。

问题:搜索时间约为10秒(我查了一下)。有没有办法减少这个时间?

1 个答案:

答案 0 :(得分:1)

您花费的时间很长,因为您正在选择所有内容然后在PHP中搜索,这真是个坏主意。建立数据库是为了搜索返回的记录集......这是你应该做的......特别是因为你每次都只返回一条记录......就像这样...

$stmt =  $mysqli->stmt_init();
if ($stmt->prepare("
    SELECT * 
    FROM table 
    WHERE BlockCode = ? 
        AND ID = ?
        AND ? NOT BETWEEN FromYear AND ToYear
    LIMIT 1
")) {
    $stmt->bind_param('s',$BlockCode);
    $stmt->bind_param('i',$ID);
    $stmt->bind_param('i',$Year);
    $stmt->execute();

    //use the output

    $stmt->close();
}
$mysqli->close();

它变慢的原因是数据库必须获取所有记录并通过管道将它们发送给必须保存/处理它们的PHP,然后执行搜索逻辑以获得结果。这就像把图书馆里的所有书籍都带回家并搜索其中一本,而不是仅仅从图书馆把这本书带回家。

同样使用预准备语句有助于系统在每次运行时优化查询,而不是每次都将查询视为新查询。

最后,根据确切的DBMS,还有许多索引,缓存和存储方法,以便加快数据库操作的结束,以便更快地返回一条记录。

如果您专注于PHP方面(在您的问题中不明确但暗示),那么您将需要调查排序算法和数据结构。例如,如果BlockCode是搜索中最重要的因素,那么使用BlockCode创建二叉树,您将看到以这种方式存储/搜索数据的性能提升......但仍然强烈怀疑关注数据库是最好的