В общем случае алгоритм очень прост:
1. Retireve строка из таблицы Student
2. Сортировка всех результирующего от # 1, используя ORDER BY выражения
3. Нанесите пункт LIMIT (+ смещение), чтобы получить порцию строк из упорядоченных результирующих, полученного из # 2
Вы можете прочитать на LIMIT здесь: http://www.postgresql.org/docs/9.4/static/queries-limit.html
в некоторых случаях LIMIT принимается во внимание при ORDER BY операций (сортировка), чтобы ускорить запрос, особенно если некоторый индекс можно использовать для устранения операции сортировки.
Вы можете изучить, как эта работа рассматривает планы объяснения.
Пусть говорят, что это индекс, созданный на этой таблице:
create index student_mark1 on student(student_marks1);
Этот запрос дает следующий объяснить план:
select * From student
order by student_marks2
limit 1;
Limit (cost=5.06..5.06 rows=1 width=178) (actual time=0.088..0.089 rows=1 loops=1)
Output: student_name, student_rollno, student_marks1, student_marks2
-> Sort (cost=5.06..5.57 rows=204 width=178) (actual time=0.088..0.088 rows=1 loops=1)
Output: student_name, student_rollno, student_marks1, student_marks2
Sort Key: student.student_marks2
Sort Method: top-N heapsort Memory: 25kB
-> Seq Scan on public.student (cost=0.00..4.04 rows=204 width=178) (actual time=0.007..0.021 rows=204 loops=1)
Output: student_name, student_rollno, student_marks1, student_marks2
Вы должны прочитать этот план от основания до до
Первая операция Seq scan
- это означает, что все строки считываются с диска (вся таблица - см. actual rows = 204
).
Затем выполняется операция сортировки (ORDER BY).
И последняя операция LIMIT 1 (в верхней части плана)
Сравните выше план по этому запросу:
select * From student
order by student_marks1
limit 1;
Limit (cost=0.14..0.24 rows=1 width=178) (actual time=0.010..0.010 rows=1 loops=1)
Output: student_name, student_rollno, student_marks1, student_marks2
-> Index Scan using student_mark1 on public.student (cost=0.14..19.20 rows=204 width=178) (actual time=0.009..0.009 rows=1 loops=1)
Output: student_name, student_rollno, student_marks1, student_marks2
Здесь сортировочная фаза пропускается, так как мы можем использовать индекс для извлечения строк в требуемом порядке (ORDER BY student_marks1 => INDEX ON Student(student_marks1)
).
Пожалуйста, обратите внимание на Actual rows = 1
в самой нижней операции: «Индексная проверка».
Это означает, что PostgreSQL не сканирует весь индекс, а извлекает только 1 (первую) строку из индекса, потому что он знает, чем запрос имеет предложение LIMIT 1. (Иногда иногда говорят, что PostgreSQL «подтолкнуло» предложение limit 1 к операции сканирования индекса и использовало его для уменьшения количества отсканированных записей в индексе).
Дополнительную информацию об использовании индексов для ускорения ORDER BY вы можете найти здесь: http://www.postgresql.org/docs/8.3/static/indexes-ordering.html
В случае, если запрос на ваш вопрос, то ORDER BY
clasue содержит выражение Student_Marks1+Student_Marks2
, а не просто столбцы. Объяснить план для этого запроса выглядит следующим образом:
select *
From student
order by student_marks1 + student_marks2
limit 2;
Limit (cost=7.10..7.11 rows=2 width=178) (actual time=0.207..0.207 rows=2 loops=1)
Output: student_name, student_rollno, student_marks1, student_marks2, (((student_marks1)::numeric + student_marks2))
-> Sort (cost=7.10..7.61 rows=204 width=178) (actual time=0.205..0.205 rows=2 loops=1)
Output: student_name, student_rollno, student_marks1, student_marks2, (((student_marks1)::numeric + student_marks2))
Sort Key: (((student.student_marks1)::numeric + student.student_marks2))
Sort Method: top-N heapsort Memory: 25kB
-> Seq Scan on public.student (cost=0.00..5.06 rows=204 width=178) (actual time=0.019..0.107 rows=204 loops=1)
Output: student_name, student_rollno, student_marks1, student_marks2, ((student_marks1)::numeric + student_marks2)
Но вы можете ускорить этот запрос создавая function based index
, таким способом:
create index student_mark12 on student((student_marks1 + student_marks2));
После создания индекса, мы имеем теперь:
Limit (cost=0.14..0.34 rows=2 width=178) (actual time=0.044..0.047 rows=2 loops=1)
Output: student_name, student_rollno, student_marks1, student_marks2, (((student_marks1)::numeric + student_marks2))
-> Index Scan using student_mark12 on public.student (cost=0.14..20.22 rows=204 width=178) (actual time=0.043..0.046 rows=2 loops=1)
Output: student_name, student_rollno, student_marks1, student_marks2, ((student_marks1)::numeric + student_marks2)
Обратите внимание, что Postgre использует индекс в данном случае, и извлекает только две записи из него (фактических строк = 2) в соответствии с пунктом LIMIT 2
.
натуральный заказ, от низкого до максимально высокий. Если столбца с числовым типом, затем сортируется на основе числового значения. Если текстовый столбец, отсортированный на основе сортировки набора символов, используется для столбца (по существу, в алфавитном порядке). Если вы хотите самый большой первый, то порядок убывания: 'order by Student_Marks desc' – DBug
@DBug Да, вы очень правы, но что делать, если я хочу заказать на основе нескольких атрибутов (или столбцов). Тогда мне любопытно узнать, какой алгоритм ранжирования использует postgresql для выполнения этого рейтинга –
Вы спрашиваете, как работает ORDER BY? –