背景信息 我有2个版本应该是相同的逻辑。第一个是有效的,第二个是给出部分结果。 我有一个接收对象数组的函数。每个对象都有一个object_id。对于数组中的每个对象,我想运行一个sql语句来从数据库中获取更多数据。
示例代码 在第一个示例中,我逐个遍历对象并执行SQL语句。我从1574条记录开始,得到1574条结果。但是,当我尝试使用所有id创建一个字符串然后将其传递给SQL“IN”命令时,我只得到800左右的结果。 这部分代码失败了:(我没有剪切和粘贴代码......只包括这里的关键部分)
public function getwidgetdetails($widgets)
{
foreach $widgets as $widget {
if isset($widget['id']) {
$list_of_ids = $widget['id'] . ',' . $list_of_ids;
}
}
//remove the trailing comma
$list_of_ids = substr($list_of_ids, 0, -1);
$temparray = explode(",", $list_of_ids);
print('<BR>temp array count:'.count($temparray) . "<BR>"); // this correctly gives 1574
$sql = "select * from object where object_id IN(". $list_of_ids. ")";
$query = $this->db->query($sql);
$all_widget_data = $query->result_array();
print(count($all_widget_data)); -- this gives 800 + records.
}
我到目前为止所做的一切
有趣的是,当我尝试通过命令行运行sql语句时,我无法在没有被切断的情况下粘贴到完整的sql语句中。我不知道命令行缓冲区有多大.. ??
问题
我的sql语句可能太长了吗? 我的另一个问题是,就sql而言,哪个更有效? 为每个对象运行单独的sql语句更好吗?或者尝试在我做的时候合并成一个? 谢谢。
答案 0 :(得分:1)
我不太清楚为什么结果会被删除(也许查询字符串太长了?)。
你可以尝试这样的事情;在哪里以块的形式查询数据库?
public function getwidgetdetails($widgets)
{
// Init
$results = array();
// Parse Ids
$list_of_ids = array();
foreach ($widgets as $widget) {
if isset($widget['id']) {
$list_of_ids[] = $widget['id'];
}
}
// Load Data In Chunk
foreach (array_chunk($list_of_ids, 250) as $ids)
{
// Query Db
$query = $this->db->query(sprintf("select * from object where object_id IN (%s)",
implode(',', $ids)));
// Append Result
$results = array_merge($results, $query->result_array());
}
// Finished
return $results;
}
答案 1 :(得分:1)
检查this。看起来in子句中字符串的大小受max_allowed_packet mysql系统变量的限制。似乎默认值为4MB,如果需要可以达到1GB。
答案 2 :(得分:0)
你的身份是否连续(不太可能)?:
如果是这样,你可以试试这个:
$sql = "select * from object where object_id BETWEEN $firstId AND $lastId";