INFORMIX-SQL 4.10.DC1 (SE Engine), в DOS 6.22, под Microsoft Virtual PC 2007, в Windows 7!
EDIT: Looking for Jonathan Leffler's wisdom on this one!
У меня есть дочерняя таблица с именем транзакция и родительская таблица с именем customer.
К этим таблицам присоединяется customer.pk_id SERIAL = transaction.fk_id INTEGER.
Таблица транзакций имеет кластеризованный индекс по fk_id, так что транзакции каждого клиента физически группируются вместе с сопоставлением данныхиндекс.Причина, по которой я выбрал кластерный индекс для fk_id, заключается в том, что большинство запросов выполняются по имени клиента, и это быстро возвращает все транзакции, принадлежащие запрашиваемому клиенту.
В таблице транзакций также есть столбец с именемaction_number SERIAL суникальный индекс.
Когда для любого клиента добавляется новая транзакция, в EOF добавляется новая строка с наибольшим номером транзакции. Примечание: Informix не поддерживает физическую кластеризацию в файле данных после создания индекса.
Поэтому, когда я хочу напечатать квитанцию клиента о последней введенной транзакции, я делаю следующий запрос:
SELECT *
FROM customer c,
transaction t
WHERE c.pk_id = t.fk_id
AND t.trx_num = (SELECT MAX(trx_num)
FROM transaction)
РЕДАКТИРОВАТЬ: существуют следующие ИНДЕКСЫ:
UNIQUE INDEX ON customer(pk_id) {SERIAL}
UNIQUE CLUSTER INDEX ON customer(last_name,sur_name,first_name,middle_name) {CHAR(30's)}
UNIQUE INDEX ON customer(ident_type,ident_num,ident_state,ident_country) {CHARS(n)}
UNIQUE CLUSTER INDEX ON transaction(fk_id) {INT}
UNIQUE INDEX ON transaction(trx_num) {SERIAL}
EDIT: EXPLAIN результаты для вышеуказанного запроса:
QUERY:
------
SELECT *
FROM customer c,
transaction t,
WHERE c.pk_id = t.fk_id
AND t.trx_num = (SELECT MAX(trx_num)
FROM transaction)
Estimated Cost: 14
Estimated # of Rows Returned: 2
1) f.transaction: INDEX PATH
(1) Index Keys: trx_num
Lower Index Filter: f.transaction.trx_num = <subquery>
2) f.customer: INDEX PATH
(1) Index Keys: pk_id
Lower Index Filter: f.customer.pk_id = f.transaction.fk_id
Subquery:
---------
Estimated Cost: 3
Estimated # of Rows Returned: 1
1) f.trx_num: INDEX PATH
(1) Index Keys: trx_num
Похоже, что оптимизатор запросов выполняет полное сканирование таблицы транзакции, чтобы найти самый большой номер транзакции, чья новая строка всегда помещается в EOF, но поскольку транзакции сгруппированы по fk_id, остальная часть транзакциичисла разбросаны по всей таблице.
Есть ли лучший способ получить более быстрое время ответа на запрос?
Поможет ли CREATE UNIQUE INDEX trxnumidx ON transaction(transaction_number) DESCENDING
быстрый поиск МАКСИМАЛЬНОГО номера транзакции?
РЕДАКТИРОВАТЬ: у меня есть аналогичный запрос, который быстро извлекает требуемую транзакцию и информацию о клиенте, так что пользователь может распечатать последнюю введенную транзакцию или любую ранее введенную транзакцию, но он требует от пользователя ввода номера транзакции:
SELECT *
FROM customer c,
transaction t
WHERE c.pk_id = t.fk_id
AND t.trx_num = $trxnum {ace input variable, type INT}
Что сбивает с толку меня в этом запросе, когда пользователь вручную вводит номер транзакции, так это то, что получение происходит мгновенно (общая стоимость = 2), где, как при автоматическом с MAX (общая стоимость = 14).. Причина, по которой я решил сделать этот запрос автоматическим, заключается в том, что в прошлом, когда пользователи вручную вводили номер транзакции, иногда они непреднамеренно вводили неправильный номер транзакции, который оказался действительным, и, не осознавая этого, они подписывали и даваликлиенту квитанцию с неверной информацией!
РЕДАКТИРОВАТЬ: DBINFO('sqlca.sqlerrd1')
будет более эффективным способом поиска последней вставленной строки?