ORDER BY #
Além de apenas encontrar as linhas a serem retornadas por uma
consulta, o índice pode entregá-las em uma ordem de classificação
específica.
Isto permite que a especificação ORDER BY de uma
consulta seja respeitada sem haver uma etapa de classificação
separada.
De todos os tipos de índice no momento com suporte pelo
PostgreSQL, apenas B-Tree
pode produzir uma saída classificada —
os outros tipos de índice retornam linhas correspondentes em uma
ordem não específica e dependente da implementação.
O planejador vai considerar satisfazer a especificação
ORDER BY varrendo um índice disponível que
corresponda à especificação, ou varrendo a tabela em ordem física
e fazendo uma classificação explícita.
Para uma consulta que requer a varredura de uma grande fração da
tabela, uma classificação explícita provavelmente será mais rápida
que usar o índice, porque requer menos E/S de disco devido a
seguir um padrão de acesso sequencial.
Os índices são mais úteis quando apenas algumas linhas precisam ser
encontradas.
Um caso especial importante é ORDER BY combinado
com LIMIT n:
uma classificação explícita terá que processar todos os dados para
identificar as primeiras n linhas,
mas se houver um índice correspondente ao ORDER BY,
as primeiras n linhas podem ser recuperadas
diretamente, sem varrer as restantes.
Por padrão, os índices B-Tree armazenam suas entradas em ordem
crescente, com valores nulos por último (o TID da tabela é tratado
como uma coluna de desempate para entradas idênticas),
significando que a varredura para frente de um índice na coluna
x produz uma saída que satisfaz
ORDER BY x (ou mais detalhadamente,
ORDER BY x ASC NULLS LAST).
O índice também pode ser varrido para trás, produzindo uma saída
que satisfaça ORDER BY x DESC (ou mais
detalhadamente, ORDER BY x DESC NULLS FIRST, uma
vez que NULLS FIRST é o padrão para
ORDER BY DESC).
A ordem de um índice B-Tree pode ser ajustada incluindo as
opções ASC, DESC,
NULLS FIRST e/ou NULLS LAST
ao criar o índice; por exemplo:
CREATE INDEX test2_info_nulls_low ON test2 (info NULLS FIRST); CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST);
Um índice armazenado em ordem crescente com nulos primeiro pode
satisfazer tanto ORDER BY x ASC NULLS FIRST,
quanto ORDER BY x DESC NULLS LAST, dependendo
da direção em que é varrido.
Você pode se perguntar por que se preocupar em fornecer todas as
quatro opções, quando duas opções, junto com a possibilidade
de varredura para trás, cobririam todas as variantes de
ORDER BY.
Em índices de uma única coluna, as opções são, na verdade, redundantes,
mas em índices multicoluna podem ser úteis.
Considere um índice de duas colunas em (x, y):
este índice pode satisfazer ORDER BY x, y
se for varrido para frente, ou
ORDER BY x DESC, y DESC se for varrido para trás.
Mas pode ser que a aplicação precise usar frequentemente
ORDER BY x ASC, y DESC.
Não há como obter esta ordenação de um índice simples, mas será possível
se o índice for definido como (x ASC, y DESC),
ou (x DESC, y ASC).
Obviamente, índices com ordenações de classificação não-padrão são um recurso bastante especializado, mas às vezes podem produzir enormes acelerações para determinadas consultas. Se vale a pena manter este índice depende da frequência com que se usa consultas que exigem uma ordem de classificação especial.