Короткий ответ
Вы можете использовать EXPLAIN
, как в EXPLAIN SELECT foo FROM table_bar
.Как интерпретировать результаты программно для «здравомыслия», однако, является гораздо более сложным вопросом.Вам понадобится программное определение «здравомыслие», например «проверяет более n строк» или «включает в себя более t таблиц».
SQL-инъекция
Вы упомянули, что ваша мотивация включает в себя желание «избежать атак SQL инъекций».Если это то, что вас беспокоит, самое важное здесь - избегать объединения любых пользовательских данных в запрос. SQL-инъекция возможна, если вы объединяете любые пользовательских данных, и их очень, очень трудно обнаружить.Гораздо лучше, просто полностью предотвратить его.
Этот код, честно говоря, заставляет мои волосы встать дыбом:
$where = "WHERE ";
foreach ($conditions as $key => $value){
$where .= "$key=" . $conditions[$key] . "&";
}
Нет способа сделать это достаточно безопасным или проверить его на предмет здравомыслия,Вы можете подумать: «Да, но все условия должны содержать только цифры», или что-то подобное, что легко проверить, но вы не можете безопасно полагаться на это.Что происходит, когда вы изменяете свой код в следующем году, или на следующей неделе, или завтра, и добавляете строковый параметр?Мгновенная уязвимость.
Вам нужно использовать подготовленные операторы, а не объединять переменные в запросе.Простого экранирования переменных недостаточно.См. Как я могу предотвратить внедрение SQL в PHP? .
Некоторые примечания по проектированию приложений
Обратите внимание, что это обычно то, что вы делаете перед развертыванием запросов в производство, а не на лету.Если вы создаете плату, позволяющую пользователям создавать свои собственные запросы, некоторая оценка запросов на лету может быть неизбежной.
Но если все, с чем вы сталкиваетесь, это множественные условия в WHERE
, тогда запросы будут быстрыми (и вам не нужно будет использовать EXPLAIN
), если выполняются две вещи:
- вы не используете подзапросы, такие как
... WHERE id IN (SELECT id from OtherTable WHERE ...) ...
и - у вас есть соответствующие индексы.(Опять же, однако, это то, что вы можете ожидать во время разработки в> 99% случаев.)
Соответствующая «Военная история», которая, надеюсь, ослабит некоторые ваши страхи
Iоднажды написал инструмент, который позволял создавать все виды сложных запросов и выполнять их с MySQL в базе данных с несколькими миллионами строк в каждой из основных таблиц.Запросы были в основном простые WHERE
условия, такие как WHERE lastOrder > '2018-01-01'
, наряду с несколькими (в основном жестко заданными) JOIN
и возможностями подзапроса.Я просто агрессивно проиндексировал, и мне никогда ничего не нужно было EXPLAIN
;это никогда не выходило за рамки производительности.