Недостаточно памяти для запуска вашего скрипта. PHP достиг предела памяти и перестает его выполнять. Эта ошибка является фатальной, сценарий останавливается. Значение предела памяти можно настроить либо в файле php.ini
, либо с помощью ini_set('memory_limit', '128 M');
в скрипте (который перезапишет значение, определенное в php.ini
). Цель ограничения памяти заключается в том, чтобы не допустить, чтобы один скрипт PHP собирал всю доступную память и приводил к остановке всего веб-сервера.
Первое, что нужно сделать, это свести к минимуму объем памяти, необходимый вашему сценарию , Например, если вы читаете большой файл в переменной или извлекаете много записей из базы данных и сохраняете их все в массиве, которые могут использовать много памяти. Измените свой код, чтобы вместо этого читать строки по строке или извлекать записи базы данных по одному, не сохраняя их все в памяти. Это требует немного концептуального понимания того, что происходит за кулисами, и когда данные хранятся в памяти и в других местах.
Если эта ошибка возникла, когда ваш сценарий не выполнял интенсивную работу с памятью, вы вам нужно проверить свой код, чтобы узнать, есть ли утечка памяти. Функция memory_get_usage
является вашим другом.
Вопросы, относящиеся:
Поместите значения во временную таблицу и затем сделайте выбор, где идентификатор в (выбирают идентификатор из поддающегося соблазну)
Я почти уверен, что можно разделить значения через несколько использование INS ИЛИ:
select * from table1 where ID in (1,2,3,4,...,1000) or
ID in (1001,1002,...,2000)
Можно попытаться использовать следующую форму:
select * from table1 where ID in (1,2,3,4,...,1000)
union all
select * from table1 where ID in (1001,1002,...)
Где Вы получаете список идентификаторов от во-первых? Так как они - идентификаторы в Вашей базе данных, они происходили из некоторого предыдущего запроса?
, Когда я видел это в прошлом, это был because:-
я думаю, что могут быть лучшие способы переделать этот код что, просто заставив этот SQL-оператор работать. Если Вы предоставляете больше подробную информацию, Вы могли бы получить некоторое представление.
Используйте... от таблицы (...:
create or replace type numbertype
as object
(nr number(20,10) )
/
create or replace type number_table
as table of numbertype
/
create or replace procedure tableselect
( p_numbers in number_table
, p_ref_result out sys_refcursor)
is
begin
open p_ref_result for
select *
from employees , (select /*+ cardinality(tab 10) */ tab.nr from table(p_numbers) tab) tbnrs
where id = tbnrs.nr;
end;
/
Это - один из редких случаев, где Вам нужна подсказка, еще Oracle не будет использовать индекс на идентификаторе столбца. Одно из преимуществ этого подхода - то, что Oracle не должна трудно анализировать запрос снова и снова. Используя временную таблицу большинство времен медленнее.
редактирование 1 упростило процедуру (благодаря jimmyorr) + пример
create or replace procedure tableselect
( p_numbers in number_table
, p_ref_result out sys_refcursor)
is
begin
open p_ref_result for
select /*+ cardinality(tab 10) */ emp.*
from employees emp
, table(p_numbers) tab
where tab.nr = id;
end;
/
Пример:
set serveroutput on
create table employees ( id number(10),name varchar2(100));
insert into employees values (3,'Raymond');
insert into employees values (4,'Hans');
commit;
declare
l_number number_table := number_table();
l_sys_refcursor sys_refcursor;
l_employee employees%rowtype;
begin
l_number.extend;
l_number(1) := numbertype(3);
l_number.extend;
l_number(2) := numbertype(4);
tableselect(l_number, l_sys_refcursor);
loop
fetch l_sys_refcursor into l_employee;
exit when l_sys_refcursor%notfound;
dbms_output.put_line(l_employee.name);
end loop;
close l_sys_refcursor;
end;
/
Это произведет:
Raymond
Hans
Я тоже оказался здесь в поисках решения.
В зависимости от максимального количества элементов, которые вам нужно запросить, и при условии, что ваши элементы уникальны, вы можете разделить свой запрос на групповые запросы по 1000 элементов и вместо этого объединить результаты на своей стороне (здесь псевдокод):
//remove dupes
items = items.RemoveDuplicates();
//how to break the items into 1000 item batches
batches = new batch list;
batch = new batch;
for (int i = 0; i < items.Count; i++)
{
if (batch.Count == 1000)
{
batches.Add(batch);
batch.Clear()
}
batch.Add(items[i]);
if (i == items.Count - 1)
{
//add the final batch (it has < 1000 items).
batches.Add(batch);
}
}
// now go query the db for each batch
results = new results;
foreach(batch in batches)
{
results.Add(query(batch));
}
Это может быть хорошим компромиссом в сценарии, когда у вас обычно не более 1000 элементов, поскольку наличие более 1000 элементов было бы вашим крайним сценарием "высокого уровня". Например, если у вас есть 1500 элементов, два запроса (1000, 500) не будут такими уж плохими. Это также предполагает, что каждый запрос сам по себе не является особенно дорогим.
Это не было бы подходящим, если бы ваше типичное количество ожидаемых элементов должно быть намного больше - скажем, в 100000 диапазон - требуется 100 запросов. Если это так, то вам, вероятно, следует более серьезно подумать об использовании решения для глобальных временных таблиц, представленного выше, как наиболее «правильного» решения. Более того, если ваши элементы не уникальны, вам также потребуется устранить повторяющиеся результаты в ваших партиях.