You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A vantagem da busca por células interiores (is_inner) é que a busca pode se restringir à BBOX (operador &&), sem conferir a interseção com o polígono. O número de células marcadas com is_inner, todavia, na maior parte dos países, não passa de 30%.
... Esquecemos que o ponto para "estar no município X" não precisa estar "dentro do polígono do município X", basta estar na sua cobertura. Usando essa propriedade podemos trocar o flag por is_not_shared (ou "is_unique"). No Brasil isso significa incluir todas as células de cobertura de litoral e fronteiras, acrescentando mais uns 20% de células municipais.
Conclusão: com a simples troca de flag chegamos nos 50% de comparações por BBOX, e excluimos elas das comparações por interseção.
Importante: a indexação GIST precisaria ser pela operação da busca, is_not_shared OR ST_Intersects(?), mas WHERE pt_geom && cell_geom AND (is_not_shared OR ST_Intersects(pt_geom,cell_geom)).
... testar com dois indices, um com outro sem o flag:
CREATE INDEX mytable_geom_idx1 ON t USING GIST (geom) WHERE is_not_shared;
Chegamos a um percentual pequeno de células não-compartilhadas... Aparentemente não há ganho, conforme explain (buffers, analyze) , quando indexamos apenas o is_contained. Mudando a estratégia... Suponha o seguinte cenário de teste:
explain (buffers, analyze)
with p AS (SELECT ST_transform(ST_Point(-45.697189,-22.686177,4326),952019) AS pt_geom, 1234as cindex)
select isolabel_ext, cindex, is_contained
from p, osmc.coverage t
where not(t.is_country) AND NOT(t.is_overlay)
ANDt.geom && p.pt_geomAND (t.is_containedOR ST_Intersects(t.geom,p.pt_geom));
Trocando operador BBOX por comparação de ID
A operação t.geom && p.pt_geom foi otimizada, é rápida, mas será que conferir um ID (do tipo hInt64) não seria ainda mais rápido?
Toda vez que buscamos um ponto, esse ponto já pode vir pronto com seu ID na origem, ou seja, o requisitante já pode fazer isso. Temos duas representações para o mesmo ponto de input, ID e geometria. Idem na tabela de coberturas (gid e geom).
Então podemos acrescentar mais uma coluna na tabela de coberturas, o gid_max para representar o limite superior da árvore à qual a célula pertence. UPDATE cover SET gid_max=hint_to_max(gid). Podemos então indexar a tabela:
CREATEUNIQUE INDEXcover_gid_idx1ON cover (gid)
WHERE NOT(is_country) AND NOT(is_overlay) AND is_not_shared
;
CREATEINDEXcover_gid_idx2ON cover (gid)
WHERE NOT(is_country) AND NOT(is_overlay) AND NOT(is_not_shared)
;
CREATEUNIQUE INDEXcover_gidmax_idx1ON cover (gid_max)
WHERE NOT(is_country) AND NOT(is_overlay) AND is_not_shared
; -- provamos que se gid é unico então gid_max é unico.CREATEINDEXcover_gidmax_idx2ON cover (gid_max)
WHERE NOT(is_country) AND NOT(is_overlay) AND NOT(is_not_shared)
;
CREATEINDEXcover_geom_idx1ON cover USING GIST (geom)
WHERE NOT(is_not_shared)
;
A consulta a analisar seria
...
WHERE NOT(t.is_country) AND NOT(t.is_overlay)
ANDp.pt_gid BETWEEN t.gidANDt.gid_maxAND (t.is_not_sharedOR ST_Intersects(t.geom,p.pt_geom));
Varbit suficiente para o teste de performance
Devido à indexação btree, a performance varbit não será pior do que bigint. Basta indexar.
Duas opções, trocar ou manter gid e incluir gid_vbit na tabela.
A vantagem da busca por células interiores (
is_inner
) é que a busca pode se restringir à BBOX (operador &&), sem conferir a interseção com o polígono. O número de células marcadas comis_inner
, todavia, na maior parte dos países, não passa de 30%.... Esquecemos que o ponto para "estar no município X" não precisa estar "dentro do polígono do município X", basta estar na sua cobertura. Usando essa propriedade podemos trocar o flag por
is_not_shared
(ou "is_unique"). No Brasil isso significa incluir todas as células de cobertura de litoral e fronteiras, acrescentando mais uns 20% de células municipais.Conclusão: com a simples troca de flag chegamos nos 50% de comparações por BBOX, e excluimos elas das comparações por interseção.
Importante: a indexação GIST precisaria ser pela operação da busca,
is_not_shared OR ST_Intersects(?)
, masWHERE pt_geom && cell_geom AND (is_not_shared OR ST_Intersects(pt_geom,cell_geom))
.... testar com dois indices, um com outro sem o flag:
... Ver https://gis.stackexchange.com/q/487330/7505
Toda célula interior é is_not_shared, mas precisamos expandir. Construção do flag is_not_shared para as células de cobertura municipal (não overlay).
Problema: isso vale para células de mesmo nível, falta remover as grandes que cobrem as pequenas.
The text was updated successfully, but these errors were encountered: