{"id":1475,"date":"2018-10-24T15:30:45","date_gmt":"2018-10-24T15:30:45","guid":{"rendered":"https:\/\/www.tiagoneves.net\/blog\/?p=1475"},"modified":"2018-10-24T15:30:45","modified_gmt":"2018-10-24T15:30:45","slug":"voce-sabe-a-diferenca-entre-uma-consulta-sargable-e-non-sargable","status":"publish","type":"post","link":"https:\/\/www.tiagoneves.net\/blog\/voce-sabe-a-diferenca-entre-uma-consulta-sargable-e-non-sargable\/","title":{"rendered":"Voc\u00ea sabe a diferen\u00e7a entre uma consulta Sargable e Non-Sargable?"},"content":{"rendered":"<p>Ol\u00e1 pessoal tudo certo?<\/p>\n<p>No post de hoje vou compartilhar com voc\u00eas a respeito de um conceito muito comum no SQL Server, que \u00e9 o conceito de SARG (&#8220;<strong>S<\/strong>&#8220;<em> search argument<\/em>) e Non-SARGable cuja a tradu\u00e7\u00e3o livre pode ser &#8220;<strong>Argumento de busca<\/strong>&#8220;.<\/p>\n<p>O termo <strong>SARG<\/strong> nada mais \u00e9 que a coluna que voc\u00ea est\u00e1 utilizando como &#8220;<strong>predicate<\/strong>&#8221; na cl\u00e1usula <strong>WHERE<\/strong> se ela pode ser utilizada em uma opera\u00e7\u00e3o de &#8220;<strong>Index Seek<\/strong>&#8220;. J\u00e1 quando o nosso &#8220;predicate&#8221; <strong>N\u00c3O<\/strong> permite a opera\u00e7\u00e3o de &#8220;Index Seek&#8221;, podemos dizer que estamos utilizando um &#8220;<em>predicate Non-Sargable<\/em>&#8221; e consequentemente teremos um <strong>custo maior<\/strong> para execu\u00e7\u00e3o da query.<\/p>\n<p>Vamos observar na pr\u00e1tica como isso funciona. Eu utilizei os scripts abaixo no banco <strong>AdventureWorks<\/strong>.<\/p>\n<pre class=\"theme:ssms2012 lang:tsql decode:true\">--Vamos retornar todos os funcion\u00e1rios com o nome \"Paul\"\r\n\r\nSELECT B.FirstName,B.LastName,A.BirthDate\r\nFROM HumanResources.Employee A\r\nJOIN Person.Person B ON B.BusinessEntityID = A.BusinessEntityID\r\nWHERE B.FirstName = 'Paul'\r\n\r\n--Custo de execu\u00e7\u00e3o\r\nTable 'Employee'. Scan count 0, logical reads 18\r\nTable 'Person'. Scan count 1, logical reads 117\r\nSQL Server Execution Times:\r\n   CPU time = 0 ms,  elapsed time = 36 ms.<\/pre>\n<p>Observando o plano de execu\u00e7\u00e3o, podemos ver que o pr\u00f3prio SQL, nos sugere a cria\u00e7\u00e3o de um \u00edndice na coluna <strong>FirstName<\/strong>.<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_1.png?ssl=1\" rel=\"lightbox[1475]\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1478\" src=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_1.png?resize=678%2C109&#038;ssl=1\" alt=\"\" width=\"678\" height=\"109\" srcset=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_1.png?w=1388&amp;ssl=1 1388w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_1.png?resize=300%2C48&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_1.png?resize=768%2C124&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_1.png?resize=1024%2C165&amp;ssl=1 1024w\" sizes=\"auto, (max-width: 678px) 100vw, 678px\" \/><\/a><\/p>\n<p>Ent\u00e3o vamos criar o \u00edndice para ver como que a consulta vai ficar.<\/p>\n<pre class=\"theme:ssms2012 lang:tsql decode:true\">CREATE INDEX IX_Person ON Person.Person\r\n(FirstName)\r\nWITH(FILLFACTOR=90)\r\n\r\n--Custo de execu\u00e7\u00e3o\r\nTable 'Person'. Scan count 1, logical reads 11\r\nTable 'Employee'. Scan count 1, logical reads 9\r\n\r\n SQL Server Execution Times:\r\n   CPU time = 0 ms,  elapsed time = 32 ms.<\/pre>\n<p>Como podemos ver o custo da execu\u00e7\u00e3o reduziu para 32 milissegundos, enquanto o numero de leituras na tabela &#8220;<strong>Person.Person<\/strong>&#8221; reduziu de 117 para apenas 9 reads. Podemos observar tamb\u00e9m que no plano de execu\u00e7\u00e3o o SQL deixou de fazer um &#8220;<strong>Index Scan<\/strong>&#8221; na tabela &#8220;Person.Person&#8221; para realizar um &#8220;<strong>Index Seek<\/strong>&#8220;. Com isso podemos dizer que a coluna &#8220;<strong>FirstName<\/strong>&#8221; para essa consulta \u00e9 um predicado <strong>Sargable<\/strong>.<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_1.1.png?ssl=1\" rel=\"lightbox[1475]\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1479\" src=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_1.1.png?resize=678%2C150&#038;ssl=1\" alt=\"\" width=\"678\" height=\"150\" srcset=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_1.1.png?w=1353&amp;ssl=1 1353w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_1.1.png?resize=300%2C66&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_1.1.png?resize=768%2C170&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_1.1.png?resize=1024%2C226&amp;ssl=1 1024w\" sizes=\"auto, (max-width: 678px) 100vw, 678px\" \/><\/a><\/p>\n<p>Mas aten\u00e7\u00e3o dependendo da consulta a coluna &#8220;FirstName&#8221; pode deixar de ser Sargable, principalmente quando utilizamos <strong>fun\u00e7\u00f5es ou utilizamos alguns operadores. <\/strong>Vejamos a query abaixo.<\/p>\n<pre class=\"lang:tsql decode:true\">SELECT B.FirstName,B.LastName,A.BirthDate\r\nFROM HumanResources.Employee A\r\nJOIN Person.Person B ON B.BusinessEntityID = A.BusinessEntityID\r\nWHERE LEFT(B.FirstName,5) = 'Paul'\r\n\r\n--Custo de execu\u00e7\u00e3o\r\nTable 'Employee'. Scan count 0, logical reads 18\r\nTable 'Person'. Scan count 1, logical reads 100\r\n SQL Server Execution Times: CPU time = 0 ms, elapsed time = 345 ms.<\/pre>\n<p>Neste primeiro exemplo &#8220;<strong>Non-Sargable<\/strong>&#8220;, estamos utilizando a fun\u00e7\u00e3o &#8220;<strong>LEFT<\/strong>&#8220;, com isso n\u00f3s impossibilitamos o otimizador de consulta a utilizar o \u00edndice para fazer a opera\u00e7\u00e3o de &#8220;<strong>Index Seek<\/strong>&#8220;.<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_2.png?ssl=1\" rel=\"lightbox[1475]\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1481\" src=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_2.png?resize=678%2C142&#038;ssl=1\" alt=\"\" width=\"678\" height=\"142\" srcset=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_2.png?w=1436&amp;ssl=1 1436w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_2.png?resize=300%2C63&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_2.png?resize=768%2C160&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_2.png?resize=1024%2C214&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_2.png?w=1356&amp;ssl=1 1356w\" sizes=\"auto, (max-width: 678px) 100vw, 678px\" \/><\/a><\/p>\n<p>Nessa segunda consulta vamos realizar um SELECT que vai nos retornar todos os funcion\u00e1rios nascidos em 1980, para isso vamos criar um \u00edndice na coluna &#8220;<strong>BirthDate<\/strong>&#8221; da tabela &#8220;<strong>HumanResources.Employee<\/strong>&#8220;.<\/p>\n<pre class=\"theme:ssms2012 lang:tsql decode:true\">CREATE INDEX IX1_Employee ON HumanResources.Employee\r\n(BirthDate)\r\nWITH(FILLFACTOR=90)\r\n\r\nSELECT B.FirstName,B.LastName,A.BirthDate\r\nFROM HumanResources.Employee A\r\nJOIN Person.Person B ON B.BusinessEntityID = A.BusinessEntityID\r\nWHERE A.BirthDate BETWEEN '1980-01-01' AND '1980-12-31'\r\n\r\n--Custo da execu\u00e7\u00e3o\r\nTable 'Person'. Scan count 0, logical reads 21\r\nTable 'Employee'. Scan count 1, logical reads 2\r\n\r\n(1 row affected)\r\n\r\n SQL Server Execution Times:\r\n   CPU time = 0 ms,  elapsed time = 450 ms.\r\n<\/pre>\n<p><a href=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_3.png?ssl=1\" rel=\"lightbox[1475]\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1483\" src=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_3.png?resize=678%2C99&#038;ssl=1\" alt=\"\" width=\"678\" height=\"99\" srcset=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_3.png?w=1599&amp;ssl=1 1599w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_3.png?resize=300%2C44&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_3.png?resize=768%2C112&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_3.png?resize=1024%2C150&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_3.png?w=1356&amp;ssl=1 1356w\" sizes=\"auto, (max-width: 678px) 100vw, 678px\" \/><\/a><\/p>\n<p>Como podemos observar, o SQL utilizou o \u00edndice para realizar uma opera\u00e7\u00e3o de &#8220;<strong>Index Seek<\/strong>&#8220;, ent\u00e3o o predicado &#8220;<strong>BirthDate<\/strong>&#8221; nesta consulta \u00e9 <strong>Sargable<\/strong>.<\/p>\n<p>Mas voc\u00ea pode estar pensando &#8220;P\u00f4 Tiago&#8221; da para deixar esse c\u00f3digo melhor utilizando a fun\u00e7\u00e3o &#8220;<strong>Year<\/strong>&#8220;, Ok&#8230;, vamos ver o que acontece se utilizarmos a fun\u00e7\u00e3o <strong>Year<\/strong>.<\/p>\n<pre class=\"theme:ssms2012 lang:tsql decode:true\">SELECT B.FirstName,B.LastName,A.BirthDate\r\nFROM HumanResources.Employee A\r\nJOIN Person.Person B ON B.BusinessEntityID = A.BusinessEntityID\r\nWHERE YEAR(A.BirthDate) = '1980'\r\n\r\n--Custo da execu\u00e7\u00e3o:\r\nTable 'Person'. Scan count 0, logical reads 21\r\nTable 'Employee'. Scan count 1, logical reads 88\r\n\r\n SQL Server Execution Times:\r\n   CPU time = 0 ms,  elapsed time = 554 ms.<\/pre>\n<p><a href=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_3.1.png?ssl=1\" rel=\"lightbox[1475]\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1492\" src=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_3.1.png?resize=678%2C100&#038;ssl=1\" alt=\"\" width=\"678\" height=\"100\" srcset=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_3.1.png?w=1424&amp;ssl=1 1424w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_3.1.png?resize=300%2C44&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_3.1.png?resize=768%2C114&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_3.1.png?resize=1024%2C152&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/Consulta_3.1.png?w=1356&amp;ssl=1 1356w\" sizes=\"auto, (max-width: 678px) 100vw, 678px\" \/><\/a><\/p>\n<p>Novamente com a utiliza\u00e7\u00e3o da fun\u00e7\u00e3o &#8220;<strong>Year<\/strong>&#8221; no predicado &#8220;<strong>BirthDate<\/strong>&#8220;, o SQL <strong>N\u00c3O<\/strong> conseguiu realizar um Index Seek.<\/p>\n<p>Mas uma coisa a se observar \u00e9 que nem sempre \u00e9 ruim voc\u00ea &#8220;pagar&#8221;, usar uma fun\u00e7\u00e3o vai ter um momento que a diferen\u00e7a no custo ser\u00e1 t\u00e3o irrelevante que n\u00e3o vai justificar o trabalho de modificar toda a query. Outro ponto de aten\u00e7\u00e3o com o predicado Sargable, est\u00e1 relacionado a <strong>convers\u00e3o impl\u00edcita<\/strong>. Quando o SQL faz uma convers\u00e3o impl\u00edcita o otimizador de consulta <strong>N\u00c3O<\/strong> consegue realizar a opera\u00e7\u00e3o de <strong>Index Seek<\/strong>, tornando ele um predicado non-sargable, como podemos observar na consulta a seguir.<\/p>\n<pre class=\"theme:ssms2012 lang:tsql decode:true\">CREATE INDEX IX1_Customer ON sales.Customer\r\n(AccountNumber)\r\nWITH (FILLFACTOR = 90)\r\n\r\nSELECT b.FirstName,\r\n       b.LastName,\r\n       a.AccountNumber\r\nFROM sales.Customer a\r\n    JOIN Person.Person b\r\n        ON b.BusinessEntityID = a.PersonID\r\nWHERE a.AccountNumber = 'AW00029594';\r\n\r\n--Custo execu\u00e7\u00e3o:\r\nTable 'Person'. Scan count 0, logical reads 3\r\nTable 'Customer'. Scan count 1, logical reads 4\r\n\r\n SQL Server Execution Times:\r\n   CPU time = 0 ms,  elapsed time = 301 ms.<\/pre>\n<p>Na consulta acima criamos um \u00edndice na tabela &#8220;<strong>Sales.Custome<\/strong>r&#8221; utilizando a coluna &#8220;<strong>AccountNumber<\/strong>&#8221; como chave, ao executar a consulta podemos observar que o SQL utilizou o \u00edndice para fazer uma opera\u00e7\u00e3o de <strong>Index Seek<\/strong>.<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_4.png?ssl=1\" rel=\"lightbox[1475]\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1485\" src=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_4.png?resize=678%2C104&#038;ssl=1\" alt=\"\" width=\"678\" height=\"104\" srcset=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_4.png?w=1354&amp;ssl=1 1354w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_4.png?resize=300%2C46&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_4.png?resize=768%2C117&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_4.png?resize=1024%2C157&amp;ssl=1 1024w\" sizes=\"auto, (max-width: 678px) 100vw, 678px\" \/><\/a><\/p>\n<p>Por\u00e9m \u00e9 normal quando o desenvolvedor utiliza algum <strong>framework<\/strong> at\u00e9 mesmo por costume colocar o par\u00e2metro &#8220;<strong>N<\/strong>&#8221; no varchar, quando fazemos isso estamos informando ao SQL que vamos trabalhar com\u00a0 o tipo de dados <strong>NVarchar<\/strong>, que neste caso vai gerar a <strong>convers\u00e3o impl\u00edcita<\/strong>, que vai fazer com que o SQL deixe de realizar o Index Seek no predicado e tamb\u00e9m consuma mais CPU para efetuar a consulta.<\/p>\n<pre class=\"theme:ssms2012 lang:tsql decode:true\">SELECT b.FirstName,\r\n       b.LastName,\r\n       a.AccountNumber\r\nFROM sales.Customer a\r\n    JOIN Person.Person b\r\n        ON b.BusinessEntityID = a.PersonID\r\nWHERE a.AccountNumber = N'AW00029594';\r\n\r\n--Custo de execu\u00e7\u00e3o:\r\nTable 'Person'. Scan count 0, logical reads 3\r\nTable 'Customer'. Scan count 1, logical reads 39\r\n\r\n SQL Server Execution Times:\r\n   CPU time = 63 ms,  elapsed time = 609 ms.<\/pre>\n<p><a href=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_4.1.png?ssl=1\" rel=\"lightbox[1475]\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1487\" src=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_4.1.png?resize=678%2C123&#038;ssl=1\" alt=\"\" width=\"678\" height=\"123\" srcset=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_4.1.png?w=1369&amp;ssl=1 1369w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_4.1.png?resize=300%2C55&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_4.1.png?resize=768%2C140&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_4.1.png?resize=1024%2C186&amp;ssl=1 1024w\" sizes=\"auto, (max-width: 678px) 100vw, 678px\" \/><\/a><\/p>\n<p>Como podemos observar o SQL gerou um &#8220;<strong>warning<\/strong>&#8221; informando que o otimizador de consulta teve que fazer uma convers\u00e3o impl\u00edcita, e por consequ\u00eancia ele nem utilizou o \u00edndice que criamos na coluna &#8220;<strong>AccountNumber<\/strong>&#8220;, realizou um <strong>Index Scan<\/strong> no \u00edndice &#8220;IX_Customer_TerritoryID&#8221;. Al\u00e9m disso o custo de execu\u00e7\u00e3o na CPU aumentou praticamente 50%, ent\u00e3o quando ocorre uma <strong>convers\u00e3o impl\u00edcita<\/strong> no predicado temos um predicado non-sargable.<\/p>\n<p>Por isso que eu sempre recomendo a observar se no plano de execu\u00e7\u00e3o n\u00e3o tem nenhum warning referente a convers\u00e3o impl\u00edcita.<\/p>\n<p>Por fim&#8230; Existe um mito bastante comum que \u00e9 falar que quando utilizamos a cl\u00e1usula <strong>LIKE<\/strong> no predicado ele deixar de ser Sargable. Isso \u00e9 verdade, por\u00e9m somente se voc\u00ea <strong>utilizar o coringa &#8220;%&#8221; no come\u00e7o e no fim da sua string de busca.<\/strong> Vejamos no exemplo a seguir.<\/p>\n<p>A query abaixo \u00e9 a mesma que utilizamos no primeiro exemplo, por\u00e9m, desta vez queremos que o SQL nos retorne todos os clientes que tenha %Paul% no nome.<\/p>\n<pre class=\"theme:ssms2012 lang:tsql decode:true\">SELECT b.fullname,\r\n       a.AccountNumber\r\nFROM sales.Customer a\r\n    JOIN Person.Person b\r\n        ON b.BusinessEntityID = a.PersonID\r\nWHERE b.FullName LIKE ('%Paul%');\r\n\r\n--Custo:\r\nTable 'Customer'. Scan count 1, logical reads 123\r\nTable 'Person'. Scan count 1, logical reads 111\r\n\r\n SQL Server Execution Times:\r\n   CPU time = 31 ms,  elapsed time = 451 ms.<\/pre>\n<p><a href=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_5.png?ssl=1\" rel=\"lightbox[1475]\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1488\" src=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_5.png?resize=678%2C136&#038;ssl=1\" alt=\"\" width=\"678\" height=\"136\" srcset=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_5.png?w=1287&amp;ssl=1 1287w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_5.png?resize=300%2C60&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_5.png?resize=768%2C154&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_5.png?resize=1024%2C205&amp;ssl=1 1024w\" sizes=\"auto, (max-width: 678px) 100vw, 678px\" \/><\/a><\/p>\n<p>Como utilizamos o no predicado <strong>FullName<\/strong> &#8220;<strong>%Paul%<\/strong>&#8220;, o otimizador de consulta <strong>N\u00c3O<\/strong> consegue efetuar um opera\u00e7\u00e3o de <strong>Index Seek<\/strong> no \u00edndice &#8220;<strong>IX02_Person<\/strong>&#8220;. Ent\u00e3o nesta consulta o predicado \u00e9 <strong>Non-Sargable<\/strong>, e at\u00e9 ai o mito que a cl\u00e1usula &#8220;<strong>LIKE<\/strong>&#8221; \u00e9 <strong>Non-Sargable<\/strong> \u00e9 verdade, mas&#8230;&#8230;<\/p>\n<p>Se voc\u00ea sabe quer somente o clientes que se chamam Paulo, Paul ou Paula, voc\u00ea concorda que podemos deixar essa consulta um pouco diferente, removendo o coringa &#8220;<strong>%<\/strong>&#8221; inicial, deixando apenas\u00a0<strong>FullName LIKE &#8220;Paul%&#8221;<\/strong>. Vamos ver o que o otimizador de consulta vai fazer nessa query.<\/p>\n<pre class=\"theme:ssms2012 lang:tsql decode:true\">SELECT b.fullname,\r\n       a.AccountNumber\r\nFROM sales.Customer a\r\n    JOIN Person.Person b\r\n        ON b.BusinessEntityID = a.PersonID\r\nWHERE b.FullName LIKE ('Paul%');\r\n\r\n--Custo:\r\nTable 'Customer'. Scan count 1, logical reads 123\r\nTable 'Person'. Scan count 1, logical reads 2\r\n\r\n SQL Server Execution Times:\r\n   CPU time = 16 ms,  elapsed time = 225 ms.<\/pre>\n<p><a href=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_5.1.png?ssl=1\" rel=\"lightbox[1475]\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1489\" src=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_5.1.png?resize=678%2C137&#038;ssl=1\" alt=\"\" width=\"678\" height=\"137\" srcset=\"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_5.1.png?w=1323&amp;ssl=1 1323w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_5.1.png?resize=300%2C61&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_5.1.png?resize=768%2C156&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/10\/consulta_5.1.png?resize=1024%2C207&amp;ssl=1 1024w\" sizes=\"auto, (max-width: 678px) 100vw, 678px\" \/><\/a><\/p>\n<p>Uauuuu agora o SQL conseguiu fazer uma opera\u00e7\u00e3o de <strong>Index Seek<\/strong> utilizando o \u00edndice &#8220;<strong>IX02_Person<\/strong>&#8220;, derrubando o mito que o <strong>LIKE<\/strong> <span style=\"color: #ff0000;\">SEMPRE<\/span> far\u00e1 que o predicado seja <strong>Non-Sargable<\/strong>.<\/p>\n<p>O <a href=\"https:\/\/fabriciolima.net\" target=\"_blank\" rel=\"noopener\">Fabricio Lima<\/a> tem um <a href=\"https:\/\/www.youtube.com\/watch?v=cyteAND34I0\" target=\"_blank\" rel=\"noopener\">v\u00eddeo<\/a> no que mostra dicas de como deixar o seu <strong>SELECT<\/strong> utilizando o <strong>LIKE<\/strong> mais perform\u00e1tico.<\/p>\n<p>Bom pessoal, por hoje \u00e9 isso espero ter contribu\u00eddo com algo novo para voc\u00eas.<\/p>\n<p>Deixe um feedback e nos ajude a melhorar.<\/p>\n<p>Abra\u00e7os,<\/p>\n<p>Tiago Neves<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ol\u00e1 pessoal tudo certo? No post de hoje vou compartilhar com voc\u00eas a respeito de um conceito muito comum no SQL Server, que \u00e9 o conceito de SARG (&#8220;S&#8220; search argument) e Non-SARGable cuja a tradu\u00e7\u00e3o livre pode ser &#8220;Argumento de busca&#8220;. O termo SARG nada mais \u00e9 que a coluna que voc\u00ea est\u00e1 utilizando&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"rop_custom_images_group":[],"rop_custom_messages_group":[],"rop_publish_now":"initial","rop_publish_now_accounts":{"twitter_91251433_91251433":""},"rop_publish_now_history":[],"rop_publish_now_status":"pending","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false,"_wpscppro_dont_share_socialmedia":false,"_wpscppro_custom_social_share_image":0,"_facebook_share_type":"","_twitter_share_type":"","_linkedin_share_type":"","_pinterest_share_type":"","_linkedin_share_type_page":"","_instagram_share_type":"","_medium_share_type":"","_threads_share_type":"","_google_business_share_type":"","_selected_social_profile":[],"_wpsp_enable_custom_social_template":false,"_wpsp_social_scheduling":{"enabled":false,"datetime":null,"platforms":[],"status":"template_only","dateOption":"today","timeOption":"now","customDays":"","customHours":"","customDate":"","customTime":"","schedulingType":"absolute"},"_wpsp_active_default_template":true},"categories":[2,220,16,26,20,239],"tags":[241,207,223,243,54,242,240],"class_list":["post-1475","post","type-post","status-publish","format-standard","hentry","category-casos-do-dia-a-dia","category-sql-server-2017","category-sqlserver-2014","category-sqlserver-2016","category-sqlserver-geral","category-tuning","tag-alwaystuningyourdata","tag-dba-es","tag-dba-remoto","tag-non-sarg","tag-performance","tag-sarg","tag-tuning"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p6eIyh-nN","jetpack-related-posts":[{"id":1495,"url":"https:\/\/www.tiagoneves.net\/blog\/dicas-de-como-realizar-um-tuning-no-sql-server\/","url_meta":{"origin":1475,"position":0},"title":"Dicas de como realizar um tuning no SQL Server","author":"tiagoneves","date":"9 de maio de 2019","format":false,"excerpt":"Ol\u00e1 pessoal tudo certo? No post de hoje, eu quero compartilhar com voc\u00eas algumas dicas de como iniciar um tuning em alguma rotina, seja stored procedure, function ou query adhoc. Quando vamos iniciar um trabalho de tuning, uma das primeiras informa\u00e7\u00f5es que precisamos \u00e9 visualizar o plano de execu\u00e7\u00e3o da\u2026","rel":"","context":"Em &quot;Casos do dia-a-dia&quot;","block_context":{"text":"Casos do dia-a-dia","link":"https:\/\/www.tiagoneves.net\/blog\/category\/casos-do-dia-a-dia\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2019\/05\/word-image-3-1.png?fit=352%2C278&ssl=1&resize=350%2C200","width":350,"height":200},"classes":[]},{"id":1035,"url":"https:\/\/www.tiagoneves.net\/blog\/eventos-da-comunidade-sql-server\/","url_meta":{"origin":1475,"position":1},"title":"Eventos da comunidade SQL Server","author":"tiagoneves","date":"19 de outubro de 2017","format":false,"excerpt":"Ol\u00e1 pessoal, tudo certo? No post de hoje vou falar sobre os \u00faltimos eventos da comunidade SQL Server no Brasil e aqui em Vit\u00f3ria. No ultimo dia 30 de Setembro, tive o prazer de palestrar no SQL Saturday em S\u00e3o Paulo, com quase 800 inscritos e mais de 30 palestras.\u2026","rel":"","context":"Em &quot;Eventos&quot;","block_context":{"text":"Eventos","link":"https:\/\/www.tiagoneves.net\/blog\/category\/eventos\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2017\/10\/4o-Encontro-PASS-Local-Group-SQL-Server-ES-07-10-2017-ISH-19.jpg?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2017\/10\/4o-Encontro-PASS-Local-Group-SQL-Server-ES-07-10-2017-ISH-19.jpg?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2017\/10\/4o-Encontro-PASS-Local-Group-SQL-Server-ES-07-10-2017-ISH-19.jpg?resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2017\/10\/4o-Encontro-PASS-Local-Group-SQL-Server-ES-07-10-2017-ISH-19.jpg?resize=700%2C400 2x, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2017\/10\/4o-Encontro-PASS-Local-Group-SQL-Server-ES-07-10-2017-ISH-19.jpg?resize=1050%2C600 3x"},"classes":[]},{"id":2227,"url":"https:\/\/www.tiagoneves.net\/blog\/sql-saturday-906-sao-paulo-vem-ai-o-maior-evento-de-dados-do-brasil\/","url_meta":{"origin":1475,"position":2},"title":"SQL Saturday #906 \u2013 S\u00e3o Paulo \u2013 Vem a\u00ed, o maior evento de dados do Brasil!","author":"tiagoneves","date":"24 de setembro de 2019","format":false,"excerpt":"Fala pessoal, tudo certo??? No pr\u00f3ximo s\u00e1bado dia 28\/09\/2019 acontece mais uma edi\u00e7\u00e3o do SQL Saturday em S\u00e3o Paulo #906 e estarei palestrando no maior evento do Brasil em tecnologias Microsoft na \u00e1rea de dados! Ser\u00e3o 42 palestras, dividas em 6 trilhas, com boa parte dos mais conhecidos especialistas da\u2026","rel":"","context":"Em &quot;Eventos&quot;","block_context":{"text":"Eventos","link":"https:\/\/www.tiagoneves.net\/blog\/category\/eventos\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2019\/09\/sqlsatsp.jpg?fit=640%2C640&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2019\/09\/sqlsatsp.jpg?fit=640%2C640&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2019\/09\/sqlsatsp.jpg?fit=640%2C640&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":1301,"url":"https:\/\/www.tiagoneves.net\/blog\/6o-encontro-do-local-group-sql-server-es\/","url_meta":{"origin":1475,"position":3},"title":"6\u00ba Encontro do Local Group SQL Server ES","author":"tiagoneves","date":"20 de fevereiro de 2018","format":false,"excerpt":"Ol\u00e1 pessoal, tudo certo? Passado o carnaval, finalmente o ano vai come\u00e7ar e que tal come\u00e7ar aprendendo SQL Server? O nosso pr\u00f3ximo encontro j\u00e1 tem data e local marcado, o 6\u00ba Encontro do Local Group SQL Server ES ser\u00e1 realizado no pr\u00f3ximo S\u00e1bado (24\/02), no Centro Universit\u00e1rio Cat\u00f3lica de Vit\u00f3ria\u2026","rel":"","context":"Em &quot;Eventos&quot;","block_context":{"text":"Eventos","link":"https:\/\/www.tiagoneves.net\/blog\/category\/eventos\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/02\/6%C2%BA-Encontro-do-Chapter-SQL-Server-ES-PASS-Local-Group-do-Esp%C3%ADrito-Santo-24_02_2018.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/02\/6%C2%BA-Encontro-do-Chapter-SQL-Server-ES-PASS-Local-Group-do-Esp%C3%ADrito-Santo-24_02_2018.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/02\/6%C2%BA-Encontro-do-Chapter-SQL-Server-ES-PASS-Local-Group-do-Esp%C3%ADrito-Santo-24_02_2018.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/02\/6%C2%BA-Encontro-do-Chapter-SQL-Server-ES-PASS-Local-Group-do-Esp%C3%ADrito-Santo-24_02_2018.jpg?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/02\/6%C2%BA-Encontro-do-Chapter-SQL-Server-ES-PASS-Local-Group-do-Esp%C3%ADrito-Santo-24_02_2018.jpg?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/02\/6%C2%BA-Encontro-do-Chapter-SQL-Server-ES-PASS-Local-Group-do-Esp%C3%ADrito-Santo-24_02_2018.jpg?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":1257,"url":"https:\/\/www.tiagoneves.net\/blog\/como-criar-uma-vm-com-o-sql-server-2017-no-azure\/","url_meta":{"origin":1475,"position":4},"title":"Como criar uma VM com o SQL Server 2017 no Azure","author":"tiagoneves","date":"6 de fevereiro de 2018","format":false,"excerpt":"Ol\u00e1 pessoal tudo certo? No post de hoje vou demonstrar como criar uma Maquina Virtual (VM) com o SQL Server 2017 no Azure. Conforme falamos no \u00faltimo post, o SQL Server 2017 \u00e9 compat\u00edvel com o Windows Server e Linux. Quando vamos criar uma VM no Azure podemos escolher qual\u2026","rel":"","context":"Em &quot;Azure&quot;","block_context":{"text":"Azure","link":"https:\/\/www.tiagoneves.net\/blog\/category\/azure\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2018\/02\/Create_VM_SQLServer2017_SSMS.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":355,"url":"https:\/\/www.tiagoneves.net\/blog\/sql-saturday-469-minhas-impressoes\/","url_meta":{"origin":1475,"position":5},"title":"SQL Saturday #469 minhas impress\u00f5es&#8230;","author":"tiagoneves","date":"24 de novembro de 2015","format":false,"excerpt":"Ol\u00e1 pessoal tudo certo? No post de hoje vou relatar um pouco do evento SQL Saturday que aconteceu no ultimo s\u00e1bado dia 21\/11 em Bras\u00edlia. O evento foi um sucesso de publico, organiza\u00e7\u00e3o e qualidade das palestras, assisti a 5 sess\u00f5es de alt\u00edssima qualidade, fora o network que acabamos fazendo.\u2026","rel":"","context":"Em &quot;Eventos&quot;","block_context":{"text":"Eventos","link":"https:\/\/www.tiagoneves.net\/blog\/category\/eventos\/"},"img":{"alt_text":"palestrantes_sqlsat469","src":"https:\/\/i0.wp.com\/www.tiagoneves.net\/blog\/wp-content\/uploads\/2015\/11\/20151121_181103.jpg?resize=350%2C200","width":350,"height":200},"classes":[]}],"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tiagoneves.net\/blog\/wp-json\/wp\/v2\/posts\/1475","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tiagoneves.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tiagoneves.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tiagoneves.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tiagoneves.net\/blog\/wp-json\/wp\/v2\/comments?post=1475"}],"version-history":[{"count":5,"href":"https:\/\/www.tiagoneves.net\/blog\/wp-json\/wp\/v2\/posts\/1475\/revisions"}],"predecessor-version":[{"id":1493,"href":"https:\/\/www.tiagoneves.net\/blog\/wp-json\/wp\/v2\/posts\/1475\/revisions\/1493"}],"wp:attachment":[{"href":"https:\/\/www.tiagoneves.net\/blog\/wp-json\/wp\/v2\/media?parent=1475"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tiagoneves.net\/blog\/wp-json\/wp\/v2\/categories?post=1475"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tiagoneves.net\/blog\/wp-json\/wp\/v2\/tags?post=1475"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}