Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Ограничения на курсоры сервера↑ ⇐ ПредыдущаяСтр 43 из 43 Содержание книги
Поиск на нашем сайте
Курсоры стороны сервера выполнены в C API через функцию mysql_stmt_attr_set(). Та же самая реализация используется для курсоров в сохраненных подпрограммах. Курсор стороны сервера позволяет набору результатов быть сгенерированным на стороне сервера, но не перемещен пользователю, кроме тех строк, которые пользователь запрашивает. Например, если пользователь выполняет запрос, но заинтересован только первой строкой, остающиеся строки не будут перемещены.
В MySQL серверные курсоры осуществлены сквозь временную таблицу. Первоначально это таблица MEMORY, но преобразованная в таблицу MyISAM, если размер достигает значения переменной системы max_heap_table_size. Одно ограничение реализации в том, что для большого набора результатов получение строк через курсор может быть медленным.
Курсоры предназначены пока только для чтения: Вы не можете использовать курсор, чтобы модифицировать строки. А поэтому обновляемые курсоры не обеспечиваются. Следовательно, UPDATE WHERE CURRENT OF и DELETE WHERE CURRENT OF не выполнены.
Курсоры не сохраняются открытыми после передачи.
Курсоры не прокручиваемые.
Курсоры не именованы. Операторный драйвер действует как курсор ID.
Вы можете иметь открытым только один курсор на подготовленную инструкцию. Если Вы нуждаетесь в нескольких курсорах, Вы должны подготовить несколько инструкций.
Вы не можете использовать курсор для инструкции, которая генерирует набор результатов, если инструкция не обеспечивается в подготовленном режиме. Это включает инструкции типа CHECK TABLES, HANDLER READ и SHOW BINLOG EVENTS.
Ограничения на подзапросы
Известная ошибка, которая будет фиксирована позже: если Вы сравниваете значение NULL с подзапросом, использующим ALL, ANY или SOME, и подзапрос возвращают пустой результат, сравнение может быть оценено к ненормативному результату NULL, а не к TRUE или FALSE.
Внешняя инструкция подзапроса может быть любой из SELECT, INSERT, UPDATE, DELETE, SET или DO.
Оптимизация подзапроса для IN не как эффективна, как для оператора = или для конструкции IN(value_list).
Типичный случай для недостаточной эффективности подзапроса IN: когда подзапрос возвращает маленькое число строк, но внешний запрос возвращает большое количество строк, которые нужно сравнить с результатом подзапроса.
Проблема состоит в том, что для инструкции, которая использует в подзапросе IN, оптимизатор перезаписывает это как соотнесенный подзапрос. Рассмотрите следующую инструкцию, которая использует несоотнесенный подзапрос:
SELECT … FROM t1 WHERE t1.a IN (SELECT b FROM t2);
Оптимизатор переписывает инструкцию к соотнесенному подзапросу:
SELECT … FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE t2.b = t1.a);
Если внутренние и внешние запросы возвращают M и N строк соответственно, время выполнения становится порядка O(M ^ N), а не O(M + N), как это было бы для несоотнесенного подзапроса.
Подзапрос IN может быть намного медленнее, чем запрос, написанный с использованием конструкции IN(value_list), которая вносит в список те же самые значения, которые возвратил бы подзапрос.
Вообще, Вы не можете изменять таблицу и выбирать из той же самой таблицы в подзапросе. Например, это ограничение применяется к инструкциям следующих форм:
DELETE FROM t WHERE … (SELECT … FROM t …); UPDATE t … WHERE col = (SELECT … FROM t …); {INSERT|REPLACE} INTO t (SELECT … FROM t …);
Исключительная ситуация: предшествующее запрещение не применяется, если Вы используете подзапрос для изменяемой таблицы в предложении FROM. Пример:
UPDATE t … WHERE col = (SELECT (SELECT … FROM t…) AS _t …);
Здесь запрещение не применяется, потому что результат от подзапроса в предложении FROM сохранен как временная таблица, так что релевантные строки в t уже были выбраны ко времени модификации t.
Операции сравнения строк обеспечиваются пока только частично:
Для expr IN (subquery), expr может быть n ‑кортеж (определенный через синтаксис конструктора строки) и подзапрос может возвращать строки n ‑кортежей.
Для expr op {ALL|ANY|SOME} (подзапрос), expr должен быть скалярным значением, и подзапрос должен быть подзапросом столбца, это не может возвращать строки с многими столбцами.
Другими словами, для подзапроса, который возвращает строки n ‑кортежей, это обеспечивается:
(val_1, …, val_n) IN (subquery)
Но это не обеспечивается: (val_1, …, val_n) op {ALL|ANY|SOME} (subquery)
Причина для обеспечения сравнений строки для IN, но не для других: IN выполнен, перезаписывая это как последовательность сравнений = и операций AND. Этот подход не может использоваться для ALL, ANY или SOME.
Конструкторы строк не оптимизированы хорошо. Следующие два выражения эквивалентны, но только второе может быть оптимизировано:
(col1, col2, …) = (val1, val2, …) col1 = val1 AND col2 = val2 AND …
Подзапросы в предложении FROM не могут быть соотнесены подзапросам. Они осуществлены (выполнены, чтобы произвести набор результатов) перед оценкой внешнего запроса, так что они не могут быть оценены на строку внешнего запроса.
Оптимизатор более отлажен для объединений, чем для подзапросов, так что во многих случаях инструкция, применяющая подзапрос, может быть выполнена более эффективно, если Вы переписываете это как объединение.
Исключительная ситуация происходит для случая, где подзапрос IN может быть переписан как объединение SELECT DISTINCT. Пример:
SELECT col FROM t1 WHERE id_col IN (SELECT id_col2 FROM t2 WHERE condition);
Эта инструкция может быть переписана следующим образом: SELECT DISTINCT col FROM t1, t2 WHERE t1.id_col = t2.id_col AND condition;
Но в этом случае объединение требует операции DISTINCT, и не более эффективно, чем подзапрос.
Возможная будущая оптимизация: MySQL не переписывает порядок объединения для оценки подзапроса. В некоторых случаях подзапрос мог бы быть выполнен более эффективно, если MySQL переписал это как объединение. Это дало бы оптимизатору возможность, чтобы выбрать между большим количеством планов выполнения. Например, это могло бы решать, читать ли одну таблицу или другую первой:
SELECT a FROM outer_table AS ot WHERE a IN (SELECT a FROM inner_table AS it WHERE ot.b = it.b);
Для этого запроса MySQL всегда просматривает сначала outer_table, а затем выполняет подзапрос на inner_table для каждой строки. Если outer_table имеет много строк, и inner_table имеет немного строк, запрос, вероятно, не будет работать с такой скоростью как могло бы быть.
Предшествующий запрос мог бы быть переписан подобно этому:
SELECT a FROM outer_table AS ot, inner_table AS it WHERE ot.a = it.a AND ot.b = it.b;
В этом случае мы можем просматривать маленькую таблицу (inner_table) и искать строки в outer_table, что будет быстро, если имеется индекс на (ot.a,ot.b).
Возможная будущая оптимизация: соотнесенный подзапрос оценен для каждой строки внешнего запроса. Лучший подход: если внешние значения строки не изменяются с предыдущей строки, чтобы не оценивать подзапрос снова. Вместо этого, используется предыдущий результат.
Возможная будущая оптимизация: подзапрос в предложении FROM оценен, осуществляя результат во временную таблицу, и эта таблица не использует индексы. Это не позволяет использование индексов по сравнению с другими таблицами в запросе, хотя это могло бы быть полезно.
Возможная будущая оптимизация: если подзапрос в предложении FROM походит на просмотр, к которому может применяться объединяющийся алгоритм, переписать запрос и применить объединяющийся алгоритм так, чтобы индексы могли использоваться. Следующая инструкция содержит такой подзапрос:
SELECT * FROM (SELECT * FROM t1 WHERE t1.t1_col) AS _t1, t2 WHERE t2.t2_col;
Инструкция может быть переписана как объединение подобно этому:
SELECT * FROM t1, t2 WHERE t1.t1_col AND t2.t2_col;
Этот тип перезаписи обеспечил бы две выгоды:
Это избегает использования временной таблицы, для которой никакие индексы не могут использоваться. В переписанном запросе оптимизатор может использовать индексы на t1.
Это дает оптимизатору большее количество свободы выбрать между различными планами выполнения. Например, перезапись запроса как объединения позволяет оптимизатору использовать сначала t1 или t2.
Возможная будущая оптимизация: для IN, = ANY, <> ANY, = ALL и <> ALL с не соотнесенными подзапросами использовать в оперативной памяти хэш для результата или временную таблицу с индексом для больших результатов. Пример:
SELECT a FROM big_table AS bt WHERE non_key_field IN (SELECT non_key_field FROM table WHERE condition)
В этом случае мы могли бы создавать временную таблицу:
CREATE TABLE t (key (non_key_field)) (SELECT non_key_field FROM table WHERE condition)
Затем для каждой строки в big_table сделайте поисковую таблицу ключа в t, основываясь на bt.non_key_field.
Ограничения на Views
Обработка View не оптимизирована:
Невозможно создать индекс на view.
Индексы могут использоваться для обработанных view, используя объединяющий алгоритм. Однако, view, который обработан алгоритмом temptable, не способен пользоваться преимуществом индексов на основных таблицах (хотя индексы могут использоваться в течение поколения временных таблиц).
Подзапросы не могут использоваться в предложении FROM view. Это ограничение будет сниматься в будущем.
Имеется общий принцип, что Вы не можете изменять таблицу и выбирать из той же самой таблицы в подзапросе.
Тот же самый принцип также применяется, если Вы выбираете из view, который выбирает из таблицы, если выбор view из таблицы в подзапросе и view оценены, используя объединяющий алгоритм. Пример:
CREATE VIEW v1 AS SELECT * FROM t2 WHERE EXISTS (SELECT 1 FROM t1 WHERE t1.a = t2.a); UPDATE t1, v2 SET t1.a = 1 WHERE t1.b = v2.b;
Если view оценен, используя временную таблицу, Вы можете выбирать из таблицы в view подзапросом и менятт ту таблицу во внешнем запросе. В этом случае view будет сохранен во временной таблице, и таким образом Вы действительно не выбираете из таблицы в подзапросе и изменяете таблицу в то же самое время. Можно принудительно предписать MySQL использовать алгоритм temptable, определяя ALGORITHM = TEMPTABLE в определении view.
Вы можете использовать DROP TABLE или ALTER TABLE, чтобы удалять или изменять таблицу, которая используется в определении view (это объявляет неверным view), и никакого предупреждения не последует. Ошибка происходит позже, когда view используется.
Определение view заморожено некоторыми инструкциями:
Если инструкция, подготовленная PREPARE, обращается к view, то содержание этого view какждый раз при выполнении инструкции будет точно соответствовать моменту ее подготовки. Это истинно, даже если определение view изменен после того, как инструкция подготовлена, но прежде, чем она выполнена. Пример:
CREATE VIEW v AS SELECT 1; PREPARE s FROM 'SELECT * FROM v'; ALTER VIEW v AS SELECT 2; EXECUTE s;
Результат, возвращенный инструкцией EXECUTE, 1, а не 2.
Если инструкция в сохраненной подпрограмме обращается к view, содержание view точно такое же, как в первый раз, когда инструкция выполнена. Например, это означает, что, если инструкция выполнена в цикле, дальнейшие итерации инструкции видят то же самое содержание view, даже если определение view изменено позже в цикле. Пример:
CREATE VIEW v AS SELECT 1; delimiter // CREATE PROCEDURE p () BEGIN DECLARE i INT DEFAULT 0; WHILE i < 5 DO SELECT * FROM v; SET i = i + 1; ALTER VIEW v AS SELECT 2; END WHILE; END; // delimiter; CALL p();
Когда процедура p() вызвана, SELECT возвращает 1 каждый раз в цикле, даже при том, что определение view изменено внутри цикла.
Относительно обновляемых view: полная цель для view состоит в том, что, если любой view является теоретически обновляемым, это должно быть обновляемым и практически. Это включает view, которые имеют UNION в их определении. В настоящее время не все просмотры, которые являются теоретически обновляемыми, таковы на деле (могут модифицироваться). Начальная реализация view была преднамеренно написана этим способом, чтобы стать пригодной для использования, обновляемые view в MySQL будут сделаны настолько быстро, насколько возможно. Многие теоретически обновляемые view могут модифицироваться теперь, но ограничения все еще существуют:
Обновляемые view с подзапросами где‑нибудь не в предложении WHERE. Некоторые view, которые имеют подзапросы в списке SELECT, могут быть обновляемыми.
Вы не можете использовать UPDATE, чтобы модифицировать больше, чем одну основную таблицу view, который определен как объединение.
Вы не можете использовать DELETE, чтобы модифицировать view, который определен как объединение.
Если пользователю предоставляют базисные привилегии, необходимые, чтобы создавать view (привилегии CREATE VIEW и SELECT), этот пользователь будут не способен вызвать SHOW CREATE VIEW на этом объекте, если пользователю не предоставляют также привилегию SHOW VIEW.
Этот недостаток может привести к проблемам при копировании базы данных с помощью mysqldump, которая может терпеть неудачу из‑за недостаточных привилегий. Эта проблема описана в Глюке #22062. Обход: чтобы администратор вручную предоставил привилегию SHOW VIEW пользователям, которым предоставляется CREATE VIEW, так как MySQL не предоставляет это неявно, когда создан view.
Ограничения на Join
Максимальное число таблиц, которые могут быть названы в одиночном объединении, составляет 61. Это также применяется к числу таблиц, которые могут быть названы в определении view.
1.4. Поведение округления 7.1 Таблицы MyISAM 7.6 Таблицы InnoDB Falcon 7.4 Таблицы HEAP 7.2 Таблицы MERGE Archive Federated MySQL Cluster CSV Blackhole Example http://forge.mysql.com/projects/search.php?t=tagk=storage%20engine PrimeBase XT (PBXT) RitmarkFS Distributed Data Engine mdbtools solidDB for MySQL Writing a Custom Storage Engine http://forums.mysql.com/list.php?105 http://www.zlib.net/ http://forums.mysql.com/list.php?112 Глюк #19307 3.3. Управление разделами MySQL Partitioning Forum Mikael Ronstrm's Blog PlanetMySQL http://dev.mysql.com/downloads/mysql/5.1.html http://forums.mysql.com/list.php?106 Глюк #16718 Глюк #14524 Глюк #17497 Глюк #15860 http://www.opengis.org/docs/99‑049.pdf http://forums.mysql.com/list.php?23 http://www.opengis.org/ http://www.opengis.org/docs/99‑049.pdf 4.2.2. Класс Geometry "4.5.2. Функции Geometry 5.2.5. Синтаксис составного оператора BEGIN … END 5.2.7. Переменные в сохраненных подпрограммах 5.2.8. Условия и драйверы 5.2.9. Курсоры 5.2.9. Курсоры 5.5. Двоичная регистрация сохраненных подпрограмм и триггеров http://forums.mysql.com/list.php?98 11.1. Ограничения на сохраненные подпрограммы и триггеры http://forums.mysql.com/list.php?99 11.4. Ограничения на Views 7.2. Синтаксис CREATE VIEW http://forums.mysql.com/list.php?100 Глюк #16420 Глюк #22830 Глюк #16409 Глюк #18896 Глюк #16522 Глюк #16396 Глюк #22830 http://www.dbazine.com/gulutzan5.shtml Глюк #18413 Глюк #16420 http://forums.mysql.com/list.php?101 http://www.unicode.org http://www.unicode.org/reports/tr10/ http://www.unicode.org/Public/UCA/4.0.0/allkeys‑4.0.0.txt http://www.iana.org/assignments/character‑sets http://support.microsoft.com/kb/170559/EN‑US/ http://www.microsoft.com/globaldev/reference/dbcs/932.htm Глюк #16072 http://d.udm.net/bar/~bar/charts/gb2312_chinese_ci.html http://recode.progiciels‑bpi.ca/showfile.html?name=dist/libiconv/gbk.h http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT http://d.udm.net/bar/~bar/charts/gbk_chinese_ci.html Глюка #12476 Глюка #13577 http://d.udm.net/bar/~bar/charts/euckr_korean_ci.html Глюк #9337 http://www.unicode.org/Public/UNIDATA/UnicodeData.txt http://www.unicode.org/Public/UCA/4.0.0/allkeys‑4.0.0.txt Глюке #16526 Глюке #12600 Глюк #4745 http://dev.mysql.com/doc/#chinese‑5.1 http://dev.mysql.com/doc/#japanese‑4.1 http://dev.mysql.com/user‑groups/ http://tinyurl.com/y6xcuf http://forums.mysql.com/list.php?103 Глюке #22062.
|
||
Последнее изменение этой страницы: 2021-01-14; просмотров: 82; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.119.132.80 (0.006 с.) |