| Primary_Filter_Efficiency<\\/td> | 19.634703196347<\\/td><\\/tr><\\/tbody><\\/table> e
| Internal_Filter_Efficiency<\\/td> | 0<\\/td><\\/tr><\\/tbody><\\/table> Não sou especialista em SQL ou índices espaciais, mas não acho que esses números sejam bons. Não é à toa que meus tempos de desenho são lentos, as consultas espaciais são morosas e em geral o banco de dados está com desempenho horrível. Cada tabela criada pelo ArcGIS tem os mesmos parâmetros de índice!
Só por diversão, vamos mudar as células por objeto alterando apenas isto no trecho de código acima:
CELLS_PER_OBJECT = 4096<\\/pre>E veja o aumento nas eficiências! Internal_Filter_Efficiency<\\/td>76.7441860465116<\\/td><\\/tr>Primary_Filter_Efficiency<\\/td>91.4893617021277<\\/p> |
Novamente, não me considero especialista em SQL Spatial Index Tuning, mas acho que estou chegando a algo aqui. Acontece que meus dados de teste consistem em "Very Complex Line Strings", que se você não vive sob uma pedra GIS é exatamente o que todos os seus dados são. Coincidentemente usar valor de 8192 para Cells Per Object neste cenário é um bom ponto de partida.< /a > </ p > < p > Mas há muitos (muitos e muitos) valores entre 16 e 8092 , e então há todas as permutações de Low , Medium , e High que poderiam ser testadas para determinar qual índice espacial é provavelmente aquele que lhe dará o melhor desempenho na maioria das vezes . E se houvesse uma maneira de testar automaticamente as configurações do índice espacial e magicamente determinar quais parâmetros se encaixam melhor no seu cenário de dados ? </ p > < p > Entre o SDE Hacker.... </ p > < p > Eu encontrei este post no geospatial - Selecting a good SQL Server 2008 spatial index with large polygons - Stack Overflow, onde alguém postou um procedimento armazenado SQL que irá percorrer tamanhos das células e níveis da grade para reportar resultados da consulta espacial para cada permutação (fornecida pelo usuário). Sendo eu um curioso por natureza , claro que quebrei o código tentando adicionar muita saída . Finalmente consegui fazê-lo funcionar . Aqui está : </ p > < p > </ p > < pre class= "lia-code-sample line-numbers language-none"> --ORIGINAL SQL CODE FROM -- http://stackoverflow.com/users/2250424/greengeo --MODIFIFIED TO INCLUDE SPATIAL INDEX HELP OUTPUT --IN TABLE   ; --!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!   ; --LOOK FOR THE EXCLAMATION POINTS IN ESTE CÓDIGO --EXISTEM VÁRIAS VARIÁVEIS FORNECIDAS PELO USUÁRIO QUE DEVEM --SER ENTRADAS PARA ESTE SP FUNCIONAR --!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
USE DATBASE GO
CREATE PROCEDURE dbo.sp_tune_spatial_index ( @tabnm VARCHAR(MAX), -- Este parâmetro armazena o nome da tabela espacial para a qual você está ajustando o índice @idxnm VARCHAR(MAX), -- Este parâmetro armazena o nome do índice espacial da tabela nomeada @min_cells_per_obj INT, -- Mínimo de Células Por Objeto para testar. Sugerido começar em 2. @max_cells_per_obj INT, -- Máximo de Células Por Objeto para testar.
\/\* O teste requer duas instâncias de geometria para usar na consulta de teste 1 e 2. A primeira deve cobrir a área da extensão padrão. A segunda deve cobrir uma área aproximadamente do tamanho da área mostrada quando ampliado, navegando ao redor. É necessário que a variável armazene uma string que criará a instância de geometria já que isso será feito dentro do procedimento e não pode ser uma variável do tipo: GEOMETRY. O SRID dessas instâncias deve corresponder ao da tabela que você está testando. *\/ @testgeom1 VARCHAR(MAX), -- Este parâmetro armazena a primeira string de criação da instância de geometria que será usada no teste @testgeom2 VARCHAR(MAX) -- Este parâmetro armazena a segunda string de criação da instância de geometria que será usada no teste
)
AS
SET NOCOUNT ON;
\/* Antes de executar este procedimento, duas tabelas são necessárias. Estas tabelas são criadas aqui para preparar a execução do procedimento. *\/
PRINT 'Verificando as tabelas necessárias...' IF EXISTS(SELECT 1 FROM sysobjects WHERE name IN ('cell_opt_perm', 'spat_idx_test_result')) BEGIN PRINT '... As tabelas "cell_opt_perm" e "spat_idx_test_result" existem.' END ELSE BEGIN PRINT '... Criando as tabelas "cell_opt_perm" e "spat_idx_test_result".' CREATE TABLE cell_opt_perm( [perm_id] [smallint] NOT NULL, [permutation] [nvarchar](4) NOT NULL, [level1] [nvarchar](6) NOT NULL, [level2] [nvarchar](6) NOT NULL, [level3] [nvarchar](6) NOT NULL, [level4] [nvarchar](6) NOT NULL )
INSERT INTO cell_opt_perm ([perm_id], [permutation], [level1], [level2], [level3], [level4]) VALUES (1,'LLLL','LOW','LOW','LOW','LOW'), (2,'LLLM','LOW','LOW','LOW','MEDIUM'), (3,'LLLH','LOW','LOW','LOW','HIGH'), (4,'LLML','LOW','LOW','MEDIUM','LOW'), (5,'LLMM','LOW','LOW','MEDIUM','MEDIUM'), (6,'LLMH','LOW','LOW','MEDIUM','HIGH'), (7,'LLHL','LOW','LOW','HIGH','LOW'), (8,'LLHM','LOW','LOW','HIGH','MEDIUM'), (9,'LLHH','LOW','LOW','HIGH','HIGH'), (10,'LMLL','LOW','MEDIUM','LOW','LOW'), (11,'LMLM','LOW','MEDIUM','LOW','MEDIUM'), (12,'LMLH','LOW','MEDIUM','LOW','HIGH'), (13,'LMML','LOW','MEDIUM','MEDIUM','LOW'), (14,'LMMM','LOW','MEDIUM','MEDIUM','MEDIUM'), (15,'LMMH','LOW','MEDIUM','MEDIUM','HIGH'), (16,'LMHL','LOW','MEDIUM','HIGH','LOW'), (17,'LMHM','LOW','MEDIUM','HIGH','MEDIUM'), (18,'LMHH','LOW','MEDIUM','HIGH','HIGH'), (19,'LHLL','LOW','HIGH','LOW','LOW'), (20,'LHLM','LOW','HIGH','LOW','MEDIUM'), (21,'LHLH','LOW','HIGH','LOW','HIGH'), (22,'LHML','LOW','HIGH','MEDIUM','LOW'), (23,'LHMM','LOW','HIGH','MEDIUM','MEDIUM'), (24,'LHMH','LOW','HIGH','MEDIUM','HIGH'), (25,'LHHL','LOW','HIGH','HIGH','LOW'), (26,'LHHM','LOW','HIGH','HIGH','MEDIUM'), (27,'LHHH','LOW','HIGH','HIGH','HIGH'), (28,'MLLL','MEDIUM','LOW','','','','') CELLS_PER_OBJECT = ' +@a1 +' , PAD_INDEX = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = ON, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 100 ) ON [PRIMARY] ' )
PRINT 'Índice reconstruído para ' +@permut SET @a3 = 1 SET @a4 = 1 WHILE @a3 < 5 BEGIN SET @start_t = GETDATE() EXEC ( 'CREATE TABLE #tmp_tab (shp GEOMETRY) DECLARE @g1 GEOMETRY SET @g1 = ' +@testgeom1 +' INSERT #tmp_tab (shp) SELECT r.Shape AS shp FROM ' +@tabnm +' r WHERE r.SHAPE.STIntersects(@g1) = 1 DROP TABLE #tmp_tab' ) SET @end_t = GETDATE() SET @elapse_t = (SELECT DATEDIFF(MS, @start_t, @end_t)) SET @num_cell = CAST(@a1 AS VARCHAR(6)) SET @time_str = CAST(@elapse_t AS VARCHAR(20)) IF @a3 = 1 BEGIN IF (SELECT TOP 1 perm_id FROM spat_idx_test_result) IS NULL BEGIN SET @perm_id = 1
END ELSE BEGIN SET @perm_id = CAST((SELECT MAX(perm_id+1) FROM spat_idx_test_result) AS VARCHAR(20)) END
EXEC
( '
INSERT INTO spat_idx_test_result (perm_id, num_cells, permut, g1t' +@a3 +') VALUES (' +@perm_id +', ' +@num_cell +', ' +@permut +', ' +@time_str +')' ) END ELSE
EXEC ( '
UPDATE spat_idx_test_result SET num_cells = ' +@num_cell +', permut = ' +@permut +', g1t' +@a3 +' = ' +@time_str +' WHERE perm_id = ' +@perm_id
) SET @a3 = @a3 + 1 END WHILE @a4 < 5 BEGIN
SET @start_t = GETDATE() EXEC ( 'CREATE TABLE #tmp_tab (shp GEOMETRY) DECLARE @g2 GEOMETRY SET @g2 = ' +@testgeom2 +' INSERT #tmp_tab (shp) SELECT nbsp; r.Shape AS shp nbsp; FROM nbsp; ' +@tabnm +' r nbsp; WHERE r.SHAPE.STIntersects(@g2) = 1 nbsp; DROP TABLE #tmp_tab' nbsp;) nbspSET @end_t = GETDATE() nbspSET @elapse_t = (SELECT DATEDIFF(MS, @start_t, @end_t)) nbspSET @num_cell = CAST(@a1 AS VARCHAR(6)) nbspSET @time_str = CAST(@elapse_t AS VARCHAR(20)) nbspEXEC nbsp( nbsp'DECLARE @geom geometry nbspDECLARE @x xml nbspDECLARE @PFVALUE float nbspDECLARE @IFVALUE float nbspDECLARE @GRIDL1VALUE int nbspDECLARE @GRIDL2VALUE int nbspDECLARE @GRIDL3VALUE int nbspDECLARE @GRIDL4VALUE int nbspDECLARE @TPIRVALUE bigint nbspDECLARE @TPIPVALUE bigint nbspDECLARE @ANOIRPBRVALUE bigint nbspDECLARE @TNOOCILFQVALUE bigint nbspDECLARE @TNOOCIL0IIVALUE bigint nbspDECLARE @TNOOCIL4IIVALUE bigint nbspDECLARE @TNOOCIL3FQVALUE bigint nbspDECLARE @TNOOCIL4FQVALUE bigint nbspDECLARE @TNOIOIL3FQVALUE bigint nbspDECLARE @TNOIOIL4FQVALUE bigint nbspDECLARE @ITTCNTLGPVALUE float nbspDECLARE @INTTTCNTLGPVALUE float nbspDECLARE @BTTCNTLGPVALUE float nbspDECLARE @ACPONTLGPVALUE float nbspDECLARE @AOPGVALUE float nbspDECLARE @NORSBPFVALUE bigint nbspDECLARE @NORSBIFVALUE bigint nbspDECLARE @NOTSFICVALUE bigint nbspDECLARE @NOROVALUE bigint nbspDECLARE @PORNBPFVALUE float nbspDECLARE @POPFRSBIFVALUE float nbspp--!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! nbspp--CERTIFIQUE-SE DE EDITAR A VARIÁVEL GEOMETRY ABAIXO PARA REPRESENTAR UM POLÍGONO nbspp--QUE ESTEJA DENTRO DA SUA CAIXA LIMITADORA nbspp--!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! nbsppSET @geom = GEOMETRY::STGeomFromText('POLYGON ((247804.201 3943957.896, 29932.568 3943963.210, 247671.344 3942876.441, 247684.630 3943652.325,247804.201 3943957.896))', 26917) nbspp--!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! nbspp--CERTIFIQUE-SE DE ESPECIFICAR O NOME DA SUA TABELA ESPACIAL nbspp--E O NOME DO ÍNDICE ESPACIAL nbspp--NAS VARIÁVEIS sp_help_spatial_geometry_index_xml nbspp--!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! nbsppexec sp_help_spatial_geometry_index_xml TEST_GEOM , S1169_idx , 1, @geom, @x output nbsppSET @PFVALUE =& nbsp ;@x.value('(\/Primary_Filter_Efficiency\/text())[1]', 'float') nbsppSET @IFVALUE =& nbsp ;@x.value('(\/Internal_Filter_Efficiency\/text())[1]', 'float') nbsppSET @GRIDL1VALUE =& nbsp ;@x.value('(\/Grid_Size_Level_1\/text())[1]', 'int') nbsppSET @GRIDL2VALUE =& nbsp ;@x.value('(\/Grid_Size_Level_2\/text())[1]', 'int') nbsppSET @GRIDL3VALUE =& nbsp ;@x.value('(\/Grid_Size_Level_3\/text())[1]', 'int') nbsppSET @GRIDL4VALUE =& nbsp ;@x.value('(\/Grid_Size_Level_4\/text())[1]', 'int') nbsppSET @TPIRVALUE =& nbsp ;@x.value('(\/Total_Primary_Index_Rows\/text())[1]', 'bigint') nbsppSET @TPIPVALUE =& nbsp ;@x.value('(\/Total_Primary_Index_Pages\/text())[1]', 'bigint') nbsppSET @ANOIRPBRVALUE =& nbsp ;@x.value('(\/Average_Number_Of_Index_Rows_Per_Base_Row\/text())[1]', 'bigint') nbsppSET @TNOOCILFQVALUE =& nbsp ;@x.value('(\/Total_Number_Of_ObjectCells_In_Level0_For_QuerySample\/text())[1]', 'bigint') nbsppSET @TNOOCIL0IIVALUE =& nbsp ;@x.value('(\/Total_Number_Of_ObjectCells_In_Level0_In_Index\/text())[1]', 'bigint') nbsppSET @TNOOCIL4IIVALUE =& nbsp ;@x.value('(\/Total_Number_Of_ObjectCells_In_Level4_In_Index\/text())[1]', 'bigint') nbsppSET @TNOOCIL3FQVALUE =& nbsp ;@x.value('(\/Total_Number_Of_ObjectCells_In_Level3_For_QuerySample\/text())[1]', 'bigint') nbsppSET @TNOOCIL4FQVALUE =& nbsp ;@x.value('(\/Total_Number_Of_ObjectCells_In_Level4_For_QuerySample\/text())[1]', 'bigint') nbsppSET @TNOIOIL3FQVALUE =& nbsp ;@x.value('(\/Total_Number_Of_Interior_ObjectCells_In_Level3_For_QuerySample\/text())[1]', 'bigint') nbsppSET @TNOIOIL4FQVALUE =& nbsp ;@x.value('(\/Total_Number_Of_Interior_ObjectCells_In_Level4_For_QuerySample\/text())[1]', 'bigint') nbsppSET @ITTCNTLGPVALUE =& nbsp ;@x.value('(\/Interior_To_Total_Cells_Normalized_To_Leaf_Grid_Percentage\/text())[1]', 'float') nbsppSET @INTTTCNTLGPVALUE =& nbsp ;@x.value('(\/Intersecting_To_Total_Cells_Normalized_To_Leaf_Grid_Percentage\/text())[1]', 'float') nbsppSET @BTTCNTLGPVALUE =& nbsp ;@x.value('(\/Border_To_Total_Cells_Normalized_To_Leaf_Grid_Percentage\/text())[1]', 'float') nbsppSET @ACPONTLGPVALUE =& nbsp ;@x.value('(\/Average_Cells_Per_Object_Normalized_To_Leaf_Grid\/text())[1]', 'float') nbsppSET @AOPGVALUE =& nbsp ;@x.value('(\/Average_Objects_PerLeaf_GridCell\/text())[1]', 'float') nbsppSET @NORSBPFVALUE =& nbsp ;@x.value('(\/Number_Of_Rows_Selected_By_Primary_Filter\/text())[1]', 'bigint') nbsppSET @NORSBIFVALUE =& nbsp ;@x.value('(\/Number_Of_Rows_Selected_By_Internal_Filter\/text())[1]', 'bigint') nbsppSET @NOTSFICVALUE =& nbsp ;@x.value('(\/Number_Of_Times_Secondary_Filter_Is_Called\/text())[1]', 'bigint') nbsppSET @NOROVALUE =& nbsp ;@x.value('(\/Number_Of_Rows_Output\/text())[1]', 'bigint') nbsppSET @PORNBPFVALUE =& nbsp ;@x.value('(\/Percentage_Of_Rows_NotSelected_By_Primary_Filter\/text())[1]', 'float') nbsppSET @POPFRSBIFVALUE =& nbsp ;@x.value('(\/Percentage_Of_Primary_Filter_Rows_Selected_By_Internal_Filter\/text())[1]', 'float') nbsppUPDATE spat_idx_test_result nbsppSET num_cells = '+@num_cell+', nbspppermut = '+@permut+', nbsppg2t'+@a4+' = '+@time_str+', nbsppPF_EFF = @PFVALUE, nbsppIF_EFF = @IFVALUE, nbsppGRIDL1 = @GRIDL1VALUE, nbsppGRIDL2 = @GRIDL2VALUE, nbsppGRIDL3 = @GRIDL3VALUE, nbsppGRIDL4 = @GRIDL4VALUE, nbsppTPIR = @TPIRVALUE, nbsppTPIP = @TPIPVALUE, nbsppANOIRPBR = @ANOIRPBRVALUE, nbsppTNOOCILFQ = @NotFoundExceptionValue, npset TNOOCIL0II=... etc.", "ms para consultar toda a geometria (Nível 3)' ,g1t4 como 'ms para consultar toda a geometria (Nível 4)' ,g2t1 como 'ms para executar consulta espacial (Nível 1)' ,g2t2 como 'ms para executar consulta espacial (Nível 2)' ,g2t3 como 'ms para executar consulta espacial (Nível 3)' ,g2t4 como 'ms para executar consulta espacial (Nível 4)' ,PF_EFF como 'Eficiência do Filtro Primário' ,IF_EFF como 'Eficiência do Filtro Interno' ,GRIDL1 como 'Tamanho da Grade Nível 1' ,GRIDL2 como 'Tamanho da Grade Nível 2' ,GRIDL3 como 'Tamanho da Grade Nível 3' ,GRIDL4 como 'Tamanho da Grade Nível 4' ,TPIR como 'Total de Linhas do Índice Primário' ,TPIP como 'Total de Páginas do Índice Primário' ,ANOIRPBR como 'Número Médio de Linhas do Índice por Linha Base' ,TNOOCILFQ como 'Número Total de Células de Objeto no Nível 0 para Amostra de Consulta' ,TNOOCIL3FQ como 'Número Total de Células de Objeto no Nível 3 para Amostra de Consulta' ,TNOOCIL4FQ como 'Número Total de Células de Objeto no Nível 4 para Amostra de Consulta' ,TNOOCIL0II como 'Número Total de Células de Objeto no Nível 0 no Índice' ,TNOOCIL4II como 'Número Total de Células de Objeto no Nível 4 no Índice' ,TNOIOIL3FQ como 'Número Total de Células de Objeto Interiores no Nível 3 para Amostra de Consulta' ,TNOIOIL4FQ como 'Número Total de Células de Objeto Interiores no Nível 4 para Amostra de Consulta' ,ITTCNTLGP como 'Porcentagem Normalizada da Relação Células Interiores para Total na Grade Folha' ,INTTTCNTLGP como 'Porcentagem Normalizada da Relação Intersectantes para Total na Grade Folha' ,BTTCNTLGP como 'Porcentagem Normalizada da Relação Borda para Total na Grade Folha' ,ACPONTLGP como 'Média de Células por Objeto Normalizada para a Grade Folha' ,AOPG como 'Média de Objetos por Célula da Grade Folha' ,NORSBPF como 'Número de Linhas Selecionadas pelo Filtro Primário' ,NORSBIF como 'Número de Linhas Selecionadas pelo Filtro Interno'  .& nbsp;,NOTSFIC como 'Número de Vezes que o Filtro Secundário é Chamado'  .& nbsp;,NORO como 'Número de Linhas Saída'  .& nbsp;,PORNBPF como 'Percentual de Linhas Não Selecionadas pelo Filtro Primário'  .& nbsp;,POPFRSBIF como 'Percentual das Linhas do Filtro Primário Selecionadas pelo Filtro Interno' FROM spat_idx_test_result ORDER BY PF_EFF | Permutação # | Células por Objeto | Grades | ms para consultar toda a geometria (Nível 1) | ms para consultar toda a geometria (Nível 2) | ms para consultar toda a geometria (Nível 3) | ms para consultar toda a geometria (Nível 4) | ms para executar consulta espacial (Nível 1) | ms para executar consulta espacial (Nível 2) | ms para executar consulta espacial (Nível 3) | ms para executar consulta espacial (Nível 4) | Eficiência do Filtro Primário | Eficiência do Filtro Interno | Tamanho da Grade Nível 1 | Tamanho da Grade Nível 2 | Tamanho da Grade Nível 3 | Tamanho da Grade Nível 4 | Total de Linhas do Índice Primário | Total de Páginas do Índice Primário | Número Médio de Linhas do Índice por Linha Base | Número Total de Células de Objeto no Nível 0 para Amostra de Consulta | Número Total de Células de Objeto no Nível 3 para Amostra de Consulta | Número Total de Células de Objeto no Nível 4 para Amostra de Consulta | Número Total de Células de Objeto no Nível 0 no Índice | Número Total de Células de Objeto no Nível 4 no Índice | Número Total de Células Interiores do Objeto no Nível 3 para AmostraDeConsulta | Número Total de Células Interiores do Objeto no Nível 4 para AmostraDeConsulta | Porcentagem Normalizada da Relação Células Interiores para Total na Grade Folha | Porcentagem Normalizada da Relação Intersectantes para Total na Grade Folha | Porcentagem Normalizada da Relação Borda para Total na Grade Folha | Média de Células por Objeto Normalizada para a Grade Folha | Média de Objetos porCélulaDaGradeFolha | Número De Linhas Selecionadas Pelo Filtro Primário | Número De Linhas Selecionadas Pelo Filtro Interno | Número De Vezes Que O Filtro Secundário É Chamado | Número De Linhas Saída | Percentual De Linhas NãoSelecionadas Pelo Filtro Primário | Percentual De Linhas Do Filtro Primário Selecionadas Pelo Filtro Interno | | 0 | 16</ TD >< TD >0< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TD >NULL< / TD >< TR >< TR >< TR > | este post nem arranha a superfície do Ajuste de Índice Espacial. Por exemplo, se você estiver usando SQL 2012, pode definir o índice para Auto Grid, que oferece 8 Níveis de Células e supostamente é uma boa combinação para ArcGIS. Você também deve observar outros fatores de desempenho, como Eficiência do Filtro Interno. Há muita Magia Negra e Medicina de Óleo de Cobra no Ajuste de Índice Espacial. Espero que este post do blog te ajude a começar na direção certa!<\/P><\/BODY><\/HTML> |