我正在尝试优化数据处理的速度,并希望对以下可扩展的解决方案提出任何建议:
我有一个PHP数组,如下所示:
$arr = array(
2543 => 1,
2123 => 2,
2431 => 1,
3223 => 3,
...
);
这里的键表示唯一的项目 ID 和这些 ID 在系统中的值、顺序。使用这个(非常大的)数组,我想提取项目,为它们分配优先级并以最有效的方式进行排序。
我目前的解决方案相当简单(使用PDO并且主要基于PHP):
$item_ids = array_keys($arr);
$item_ids_csv = implode(",", $item_ids);
$sql = "SELECT `id`,`name`
FROM `item_data`
WHERE `id` IN ($item_ids_csv);";
#execute is a custom function returning a PDO execution
$items = $this->execute($sql)->fetchAll(PDO::FETCH_ASSOC);
foreach($items as &$item){
$item['order'] = $arr[$item['id']];
}
usort($items, function($a, $b) {
return $a['order'] - $b['order'];
});
print_r($items);
这工作得很好,但我想知道上述 PHP 操作是否完全可以在 SQL 中实现?也许我可以INNER JOIN
每个 id ON
订单并ORDER BY
这些?
我正在计算它为我节省了一些处理时间,以将此逻辑转移到数据库,如果我错了,请纠正我。
值拆分为三组来使用单个查询在数据库中执行排序:
select id, name
from item_data
order by (id in ($items_ids_csv_1)) desc,
(id in ($items_ids_csv_2)) desc,
(id in ($items_ids_csv_3)) desc;
这是因为表达式id in (...)
当id
在列表中时返回"1",否则返回"0"。
正如我在评论中建议的那样,如果只有 3 个序列值,请将其分为 3 个部分:
# make 3 different $item_ids_csv
$item_ids_csv_1 = ...
$item_ids_csv_2 = ...
$item_ids_csv_3 = ...
...
$sql = "SELECT `id`,`name`,1 AS seq
FROM `item_data`
WHERE `id` IN ($item_ids_csv_1)
UNION
SELECT `id`,`name`,2 AS seq
FROM `item_data`
WHERE `id` IN ($item_ids_csv_2)
UNION
SELECT `id`,`name`,3 AS seq
FROM `item_data`
WHERE `id` IN ($item_ids_csv_3)
ORDER BY seq, id;";