我正在尝试优化数据处理的速度,并希望对以下可扩展解决方案有任何建议:
我有一个PHP数组看起来像:< / p>
$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
订单ON
每个ID和ORDER BY
这些?
我觉得它伤害了我一些处理时间,把这个逻辑转移到数据库,如果我错了就纠正我。
答案 0 :(得分:1)
您可以在数据库中进行排序,通过将值分为三组来进行单个查询:
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”。
答案 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;";