【发布时间】:2017-05-18 07:07:08
【问题描述】:
我们需要按日期列出和排序几个事件。事件存储在多个表中,并由多个查询选择。我们不能使用 union + order by,因为一张表可能有 3-4 列,而另一张表大约有 20 列。
我们提出了以下解决方案:
$stmt = $db->query("
SELECT 'login' table, id, created
FROM login
WHERE date(created) BETWEEN 'somedate' AND 'somedate'
UNION
SELECT 'order' table, id, created
FROM order
WHERE date(created) BETWEEN 'somedate' AND 'somedate'
UNION
SELECT 'receipt' table, id, created
FROM receipts
WHERE date(created) BETWEEN 'somedate' AND 'somedate'
ORDER BY created
");
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$sorted[] = array(
"table" => $row['table'],
"id" => $row['id']
);
}
foreach (array_chunk($sorted, 5000) as $dataChunk) {
foreach ($dataChunk as $row) {
if ($row['table'] == "login") {
$stmt = $db->query("
SELECT some columns
FROM logins
WHERE id = ".$row['id']."
");
$row_count = $stmt->rowCount();
if ($row_count != '0') {
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
do something
}
}
}
if ($row['table'] == "order") {
$stmt = $db->query("
SELECT some columns
FROM logins
WHERE id = ".$row['id']."
");
$row_count = $stmt->rowCount();
if ($row_count != '0') {
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
do a lot here
}
}
}
if ($row['table'] == "receipt") {
$stmt = $db->query("
SELECT some columns
FROM logins
WHERE id = ".$row['id']."
");
$row_count = $stmt->rowCount();
if ($row_count != '0') {
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
do something
}
}
}
}
}
使用此解决方案将对我们的数据库进行数千次查询,所以我们的问题是 - 能否以更好的方式完成?
希望收到你们的来信...谢谢!
【问题讨论】:
-
order是一个保留字,所以上面的内容并不完全正确。 -
哦,但这只是一个例子。我们实际上使用“ordre”,这是挪威语的订单。上面的代码工作正常,只是我认为这是更好的方法。
-
您可以使用联合,您只需在引用表的查询中创建具有较少列的虚拟列。另一种可能性是定义一组公共列并将它们作为每个查询中的列,然后对于那些具有多个基本列的列,使用 concat 为该表唯一的列创建具有名称/值对的单个列。您甚至可以将其格式化为 JSON 以使它们更容易爆炸。
-
嗯..虽然有点乱,但由于单个查询,也许是更好的解决方案?
标签: php mysql optimization