Недостаточно памяти для запуска вашего скрипта. PHP достиг предела памяти и перестает его выполнять. Эта ошибка является фатальной, сценарий останавливается. Значение предела памяти можно настроить либо в файле php.ini
, либо с помощью ini_set('memory_limit', '128 M');
в скрипте (который перезапишет значение, определенное в php.ini
). Цель ограничения памяти заключается в том, чтобы не допустить, чтобы один скрипт PHP собирал всю доступную память и приводил к остановке всего веб-сервера.
Первое, что нужно сделать, это свести к минимуму объем памяти, необходимый вашему сценарию , Например, если вы читаете большой файл в переменной или извлекаете много записей из базы данных и сохраняете их все в массиве, которые могут использовать много памяти. Измените свой код, чтобы вместо этого читать строки по строке или извлекать записи базы данных по одному, не сохраняя их все в памяти. Это требует немного концептуального понимания того, что происходит за кулисами, и когда данные хранятся в памяти и в других местах.
Если эта ошибка возникла, когда ваш сценарий не выполнял интенсивную работу с памятью, вы вам нужно проверить свой код, чтобы узнать, есть ли утечка памяти. Функция memory_get_usage
является вашим другом.
Вопросы, относящиеся:
Когда я смотрю на сложный бит кода SQL, это - то, что я делаю.
Первый, если это - обновление или удаляет, я добавляю код (если это не там и прокомментировано) сделать его выбором. Никогда не попробуйте обновление или удалите впервые, не видя результаты в выборе сначала. Если это - обновление, я удостоверяюсь, что выбор показывает текущее значение и что я буду устанавливать его на то, чтобы удостовериться, что я получаю желаемый результат.
Понимание соединений очень важно для понимания сложного SQL. Для каждого соединения я спрашиваю меня, почему это здесь? Существует четыре основных причины. Вам нужен столбец для выбора, Вам нужно поле для, где пункт, Вам нужно соединение как мост к третьей таблице, или необходимо соединить с таблицей для фильтрации записей (таких как получение деталей о клиенте, у кого есть заказы, но не необходимость в подробных сведениях о заказе, это может часто добиваться большего успеха с, ЕСЛИ СУЩЕСТВУЕТ где пункт). Если это - левое или правое соединение (я склонен переписывать так, все - левое соединение, которое делает жизнь более простой.), я рассматриваю, работало ли внутреннее объединение. Почему мне нужно левое соединение? Если я не буду знать ответ, я буду выполнять его оба пути и видеть то, что различие в данных. Если будут полученные таблицы, я посмотрю на тех сначала (работающий просто, что часть выбора для наблюдения то, что результат) для понимания, почему это там. Если будут подзапросы, я попытаюсь понять их и если они будут медленными, то попытается преобразовать в полученную таблицу вместо этого, поскольку те часто намного быстрее.
Затем, я смотрю эти where
пункты. Это - одно место, где прочная основа в Вашей конкретной базе данных пригодится. Например, я знаю в своих базах данных, какие случаи я, возможно, должен был бы видеть только почтовый адрес и какие случаи я, возможно, должен был бы видеть другие адреса. Это помогает мне знать, отсутствует ли что-то в где пункт. Иначе я рассматриваю каждый объект в where
пункт и фигура, почему это должно было бы быть там, тогда я рассматриваю, существует ли что-нибудь отсутствующее, который должен быть там. После просмотра его я рассматриваю, могу ли я внести изменения для создания запроса sargable.
я также рассматриваю любые сложные биты списка выборки затем. Что делает тот оператор выбора? Почему там подзапрос? Что делают те функции? (Я всегда ищу функциональный код для любой функции, с которой я не уже знаком.), Почему там отличное? Это может быть избавлено от при помощи полученной таблицы или агрегатной функции и группы операторами?
Наконец и самый важный , я выполняю выбор и определяю, выглядят ли результаты корректными на основе моего знания бизнеса. , Если Вы не понимаете своего бизнеса, Вы не будете знать, ли запрос корректен . Синтаксически корректный не означает правильные результаты. Часто существует часть Вашего существующего пользовательского интерфейса, который можно использовать в качестве руководства по тому, корректны ли результаты. Если у меня есть экран, который показывает заказы на клиента, и я делаю отчет, который включает потребительские заказы, я мог бы выборочная проверка несколько отдельных клиентов, чтобы удостовериться, что она показывает правильный результат.
, Если текущий запрос фильтрует неправильно, я удалю биты его для обнаружения то, что избавляется от записей, которые я не хочу или добавляющие, которые я не хочу. Часто Вы будете находить, что соединение является тем многим, и Вам нужен тот к одному (используйте полученную таблицу в этом случае!) или Вы найдете, что некоторая информация, что Вы думаете, что Вам нужно в where
, пункт не верен для всех данных, в которых Вы нуждаетесь или что некоторая часть where
пункт отсутствует. Это помогает иметь все поля в where
пункт (если они уже не были в выборе) в выборе в то время, когда Вы делаете это. Это может даже помочь показать все поля из всех объединяемых таблиц и действительно посмотреть на данные. Когда я делаю это, я часто добавляю маленький бит к, где пункт для захвата просто некоторых записей, которые я имею, который не должен быть там, а не все записи.
Одна подлая вещь, которая повредит много запросов, where
пункт, ссылающийся на поле в таблице на правой стороне левого соединения. Это превращает его во внутреннее объединение. При реальной необходимости в в левом соединении необходимо добавить те виды условий к самому соединению.
Я разламываю его на меньшие запросы (вот почему, мне нравятся подзапросы больше, чем СОЕДИНЕНИЯ)
Иногда, я даже сохраняю результаты подзапроса как таблица и использование это в основном запросе. Это несколько похоже на упрощение выражения кода путем сохранения битов в локальные переменные и затем работы на локальные переменные в следующей части выражения.
я - фанатик о всегда использовании псевдонимов таблицы (например, CLIENT_HISTORY_ITEM T1) и круглые скобки вокруг выражений критериев. Я часто изменяю число псевдонима таблицы приблизительно на десять для каждой части запроса, таким образом, я вижу то, что прибывает из где:
ИЗБРАННЫЙ T1. Идентификатор ОТ TABLE1 T1, ГДЕ T1. ДАТА = (ВЫБИРАЮТ МАКСА (T11. ДАТА) ОТ TABLE1 T11, ГДЕ (T1. ОБЛАСТЬ = T11. ОБЛАСТЬ))
Аплодисменты
При использовании PostgreSQL инкапсуляция представления замечательна для этого.
Использование CTEs или полученных таблиц (в SQL MS, по крайней мере) может быть полезным для форматирования SQL-оператора, не разделяя его на отдельные запросы с помощью временных таблиц для "присоединений" к ним.
я соглашаюсь с другими, что упомянутые запросы довольно просты.
я смотрю на в c# и задаюсь вопросом, почему у Вас есть столько строк для простой обработки нескольких тысяч строк...
Если бы они дают Вам паузу, я предложил бы выписать таблицы на бумаге для получения лучшего ощущения того, что это означает присоединяться к вещам вместе.
предположим, например, что у Вас есть таблица для Книг и таблица за Цены. Таблица Prices может иметь многократные въезды для каждой книги (так как цена может измениться).
, Если Вы хотите получить список текущих книг и цен, необходимо присоединиться к этим двум таблицам вместе.
я работал бы через это над бумагой путем привлечения стрелок между каждой книгой и ее соответствующей "текущей" ценой. Тогда я записал бы, что в логику, которая станет частью условия объединения или подзапроса.
, Как только Вы приобретаете навык его, сложные запросы становятся легче проанализировать.
Вы делаете то, что я делаю. Мой первый инструмент для того, чтобы сделать запрос понятным является хорошей визуальной организацией, которую люди в вопросе, на который Вы ссылаетесь, главным образом делают и тестируют в управляемых блоках с помощью ПРЕДЕЛЬНЫХ пунктов. Если несвязанные подзапросы включены, они могут быть выполнены отдельно, конечно. Если существует чудодейственное средство, тем не менее, я не знаю об этом.
Как с чем-либо, Лучший способ состоит в том, чтобы записать много сложных SQL-операторов самостоятельно. В конечном счете общий способ, которым структурированы вещи, становится очевидным. Конечно, если Вы ищете что-то быстрое, которое, вероятно, не является путем.
Пробел очень важен. Запрос, который выглядит невероятно сложным, может выглядеть почти упрощенным, когда надлежащий пробел присутствует.
относительно соединений... Ну, я сожалею, но я не могу быть очень услужливым здесь, потому что мой ответ - то, что лучший способ понять конкретное соединение состоит в том, чтобы понять, как соединения работают в целом. Каждый тип соединения служит очень определенной цели и если Вы знаете, как они работают, не должно действительно быть большой части различия от присоединения x к y, x к y к z или X и Y к a и b.
то, Что может помочь более сразу, однако, знает, что необходимо посмотреть на самые внутренние части сначала. В противоположность коду, где Вы, вероятно, привыкли к рассмотрению вещей в большом масштабе, тогда роющем в гранулярность с запросом, это более полезно и легко понять, начинаете ли Вы с гранулярности и прокладываете себе путь исходящие.
Запускают с любых подзапросов, выясняют то, что они делают в отдельных частях, рассматривающих его как единый запрос (если возможный), тогда постепенно съезжают шаг за шагом, пока Вы не наверху. Еще раз, на соединениях... Действительно, просто пойдите, находят веб-страницу, которая объясняет соединения, и сделайте некоторые тесты, пока Вы полностью не понимаете их. Нет действительно способа сделать это легче, как, как только Вы понимаете их, можно в значительной степени выяснить что-либо с соединениями, которые Вы хотите.
Другой importan является синтаксисом соединения стандарта использования:
SELECT A
FROM B
JOIN C ON B.ID = C.ID
WHERE C.X = 1
Вместо
SELECT A
FROM B
, C
WHERE B.ID = C.ID
AND C.X = 1
Я предполагаю, что все это зависит от опыта. Я не нашел запросы в этом вопросами быть очень сложным, возможно, так как большинство запросов, которые я выполняю, более сложно, чем те.
Надлежащие стандарты кодирования, конечно, помогают запросам понимания, поскольку это позволяет повреждать его в визуально меньшие и лучшие отформатированные блоки. Когда подзапросы включены, лучше понять то, что те делают сначала и использование что, понимая при рассмотрении полного запроса.
форматирование помогает, но понимающий теорию множеств и следовательно, реляционная теория, помогает еще больше.
неопределенное понимание того, как запросы выполняются, не причинит ни одному боль (сканирования таблицы, индексные сканирования, индексные переходы, слияния хеш-таблицы, и т.д.); планировщик запроса может показать Вам эти операции
несколько операций (наличие, существует, с) может быть неприятным в первом
, понимают сначала, что происходит с каждой таблицей, и как к таблицам присоединяются
Добавление отступа и комментарии помогают много. Самой ценной вещью, с которой я столкнулся, является оператор WITH. Это находится в Oracle и имеет дело с рефакторингом подзапроса. Это позволяет Вам повреждать выполнение больших запросов в ряд по-видимому меньших. Каждый просто немного более управляемый.
Вот пример
WITH
ssnInfo AS
(
SELECT SSN,
UPPER(LAST_NAME),
UPPER(FIRST_NAME),
TAXABLE_INCOME,
CHARITABLE_DONATIONS
FROM IRS_MASTER_FILE
WHERE STATE = 'MN' AND -- limit to in-state
TAXABLE_INCOME > 250000 AND -- is rich
CHARITABLE_DONATIONS > 5000 -- might donate too
),
doltishApplicants AS
(
SELECT SSN,
SAT_SCORE,
SUBMISSION_DATE
FROM COLLEGE_ADMISSIONS
WHERE SAT_SCORE < 100 -- About as smart as a Moose.
),
todaysAdmissions AS
(
SELECT doltishApplicants.SSN,
TRUNC(SUBMISSION_DATE) SUBMIT_DATE,
LAST_NAME, FIRST_NAME,
TAXABLE_INCOME
FROM ssnInfo,
doltishApplicants
WHERE ssnInfo.SSN = doltishApplicants.SSN
)
SELECT 'Dear ' || FIRST_NAME ||
' your admission to WhatsaMattaU has been accepted.'
FROM todaysAdmissions
WHERE SUBMIT_DATE = TRUNC(SYSDATE) -- For stuff received today only
;
, то же самое может быть сделано со встроенными представлениями, но с также имеет способность составить временные таблицы при необходимости. В некоторых случаях можно скопировать подзапрос и выполнить его вне контекста выполнения больших запросов.
Эта форма также позволяет Вам помещать пункты фильтра с отдельным подзапросом и сохранять присоединяющиеся пункты для заключительного выбора.
На работе, наша группа разработки обычно находит их легче поддержать, и часто быстрее.
Вот процедура для следования для распутывания запроса.
Выполнение каждого из них обычно позволяет мне получать лучшую власть, что происходит в запросе.
Главным образом это - просто опыт и надлежащее расположение с отступом.
Они могут быть некоторыми полезными подсказками..
, Например:
select ID, Description, Status from ABC where Status = 1 OR Status = 3
мог быть лучше записан как:
select
ID,
Description,
Status
from ABC
where
Status = 1 OR
Status = 3
с более сложным запросом, Вы видели бы намного большее преимущество.