Эффективный выбор данных sql - PullRequest
3 голосов
/ 27 мая 2010

У меня очень большая таблица с более чем 1000 записями и 200 столбцами. Когда я пытаюсь получить записи, соответствующие некоторым критериям в предложении WHERE, используя оператор SELECT, это занимает много времени. Но большую часть времени я просто хочу выбрать одну запись, которая соответствует критериям в предложении WHERE, а не все записи.

Полагаю, должен быть способ выбрать только одну запись и выйти, что минимизирует время поиска. Я попытался ROWNUM=1 в предложении WHERE, но на самом деле это не сработало, потому что, по-моему, движок все еще проверяет все записи даже после нахождения первой записи, соответствующей критерию WHERE. Есть ли способ оптимизации в случае, если я хочу выбрать всего несколько записей?
Заранее спасибо.

Изменить:

Я использую оракул 10 г. Запрос выглядит так:

Select * 
from Really_Big_table 
where column1 is NOT NULL 
and column2 is NOT NULL 
and rownum=1;

Кажется, это работает медленнее, чем версия без rownum = 1;

Ответы [ 5 ]

1 голос
/ 27 мая 2010

1000 записей - это не много данных в таблице. 200 столбцов - это достаточно широкая таблица. По этой причине я бы посоветовал вам не иметь дело с действительно большой таблицей - я выполнил запросы к миллионам строк без проблем.

Вот небольшой эксперимент ... сколько времени это займет, по сравнению с запросом "SELECT *"?

SELECT
    Really_Big_table.Id
FROM
    Really_Big_table
WHERE 
    column1 IS NOT NULL
AND
    column2 IS NOT NULL
AND
    rownum=1;
1 голос
/ 27 мая 2010

rownum - это то, что вы хотите, но вам нужно выполнить основной запрос как подзапрос.

Например, если ваш оригинальный запрос:

  SELECT co1, col2
    FROM table
    WHERE condition

тогда вам стоит попробовать

  SELECT *
  FROM (
    SELECT col1, col2
      FROM table
      WHERE condition
  ) WHERE rownum <= 1

См. http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html, чтобы узнать, как rownum работает в Oracle.

0 голосов
/ 27 мая 2010

это не должно занять много времени для запроса таблицы 1000 строк. Однако есть исключения, проверьте, находитесь ли вы в одном из следующих случаев:

1. Много строк было удалено

В прошлом в таблице было огромное количество строк. Поскольку отметка максимальной воды ( HWM ) все еще остается высокой (удаление не понизит ее) и FULL TABLE SCAN считывает все данные до отметки максимальной отметки, для возврата результатов может потребоваться много времени даже если таблица сейчас почти пуста.

Анализ вашей таблицы (dbms_stats.gather_table_stats('<owner>','<table>')) и сравнение пространства, фактически используемого строками (пространство на диске), с эффективным пространством (данными), например:

SELECT t.avg_row_len * t.num_rows data_bytes, 
       (t.blocks - t.empty_blocks) * ts.block_size bytes_used
  FROM user_tables t
  JOIN user_tablespaces ts ON t.tablespace_name = ts.tablespace_name
 WHERE t.table_name = '<your_table>';

Вам нужно будет учитывать накладные расходы на строки и блоки, а также пространство, зарезервированное для обновления (PCT_FREE). Если вы видите, что используете намного больше места, чем требуется (типичные издержки ниже 30%, YMMV), вы можете сбросить HWM, либо:

  • ALTER TABLE <your_table> MOVE; и затем перестройте ИНДЕКС (ALTER INDEX <index> REBUILD), не забудьте впоследствии собрать статистику.
  • использовать DBMS_REDEFINITION

2. Таблица имеет очень большие столбцы

Проверьте, есть ли у вас столбцы типа данных LOB, CLOB, LONG (irk) и т. Д. Данные размером более 4000 байтов в любом из этих столбцов хранятся вне строки (в отдельном сегменте), что означает, что если вы этого не сделаете выберите эти столбцы, вы будете запрашивать только другие меньшие столбцы.

Если вы в этом случае, не используйте SELECT *. Либо вам не нужны данные в больших столбцах, либо используйте SELECT rowid, а затем выполните второй запрос: SELECT * WHERE rowid = <rowid>.

0 голосов
/ 27 мая 2010

Пример здесь: Вы можете посмотреть больше здесь

SELECT ename, sal 
FROM ( SELECT ename, sal, RANK() OVER (ORDER BY sal DESC) sal_rank
              FROM emp ) 
WHERE sal_rank <= 1;

Вы также должны выполнить некоторую индексацию столбцов для столбца в предложении WHERE

0 голосов
/ 27 мая 2010

В SQL большая часть оптимизации происходит в форме индекса по таблице (где вы будете индексировать столбцы, которые отображаются в столбцах WHERE и ORDER BY в качестве приблизительного ориентира).

Вы не указали, какую базу данных SQL вы используете, поэтому я не могу указать на хороший ресурс.

Здесь - введение в индексы в Oracle.

Здесь еще один учебник.

Что касается запросов - вы всегда должны указывать столбцы, которые вы возвращаете, и не использовать бланк *.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...