AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 118666
Accepted
cocogorilla
cocogorilla
Asked: 2015-10-21 12:40:55 +0800 CST2015-10-21 12:40:55 +0800 CST 2015-10-21 12:40:55 +0800 CST

impedir operador de inserção de índice clusterizado em exibição indexada não qualificada

  • 772

Alguém sabe uma solução alternativa para isso? Essencialmente, o procedimento armazenado força um operador de inserção na exibição indexada, mesmo que as linhas não sejam qualificadas. Como resultado, há um erro de conversão. No entanto, para ad hocs, o sql elimina corretamente a exibição da consideração.

Considere o seguinte esquema:

create table testdata (
    testid int identity(1,1) primary key
  , kind varchar(50)
  , data nvarchar(4000))
go
create view integer_testdata with schemabinding
as
select cast(a.data as int) data, a.kind, a.testid
  from dbo.testdata a
 where a.kind = 'integer'
go
create unique clustered index cl_intdata on integer_testdata(data)
go
create procedure insert_testdata
(
    @kind varchar(50)
  , @data nvarchar(4000)
)
as
begin
  insert into testdata (kind, data) values (@kind, @data)
end
go

Todos estes funcionam:

insert into testdata (kind, data) values ('integer', '1234');
insert into testdata (kind, data) values ('integer', 12345);
insert into testdata (kind, data) values ('noninteger', 'noninteger');
exec insert_testdata @kind = 'integer', @data = '123456';
exec insert_testdata @kind = 'integer', @data = 1234567;

Isso falha:

exec insert_testdata @kind = 'noninteger', @data = 'noninteger';

Uma comparação dos "planos de execução estimados":

insert into testdata (kind, data) values ('noninteger', 'noninteger'): insira a descrição da imagem aqui

exec insert_testdata @kind = 'noninteger', @data = 'noninteger': insira a descrição da imagem aqui

sql-server
  • 1 1 respostas
  • 232 Views

1 respostas

  • Voted
  1. Best Answer
    Vladimir Baranov
    2015-10-24T18:31:14+08:002015-10-24T18:31:14+08:00

    Obrigado por fornecer um script completo para recriar o problema.

    Eu testei com o SQL Server 2014 Express.

    Quando eu adiciono OPTION(RECOMPILE)funciona:

    ALTER procedure [dbo].[insert_testdata]
    (
        @kind varchar(50)
      , @data nvarchar(4000)
    )
    as
    begin
      insert into testdata (kind, data) 
      values (@kind, @data)
      OPTION(RECOMPILE);
    end
    

    Quando eu executo isso no SSMS:

    exec insert_testdata @kind = 'noninteger', @data = 'noninteger';
    

    Eu recebo esta mensagem:

    (1 row(s) affected)
    

    e uma linha é adicionada à tabela.

    Qual versão do SQL Server você está usando? Lembro vagamente que nas versões anteriores a 2008 isso OPTION(RECOMPILE)se comportava um pouco diferente.


    Estou trabalhando com uma estrutura de dados existente e preciso de uma pesquisa rápida em valores inteiros exclusivos armazenados no subconjunto de nvarchar(4000), um filtro em outra coluna define esse subconjunto de linhas.

    Nesse caso, pode ser melhor usar o índice filtrado em vez da exibição indexada:

    CREATE UNIQUE NONCLUSTERED INDEX [IX_DataFiltered] ON [dbo].[testdata]
    (
        [data] ASC
    )
    WHERE ([kind]='integer')
    

    O otimizador deve usar esse índice quando o WHEREfiltro da consulta corresponder exatamente à WHEREcláusula do índice.

    Sim, aqui o índice está na nvarcharcoluna, o que pode não ser a melhor coisa, especialmente se você juntar esta tabela com uma intcoluna de outra tabela ou tentar filtrar valores nesta coluna usando intvalues.


    Outra variante que vem à mente é a coluna computada persistente que converte nvarcharem int. Em essência, é muito semelhante à sua exibição, mas os nvarcharvalores persistentes convertidos intsão armazenados na mesma tabela, não em um objeto separado.

    CREATE TABLE [dbo].[testdata](
        [testid] [int] IDENTITY(1,1) NOT NULL,
        [kind] [varchar](50) NULL,
        [data] [nvarchar](4000) NULL,
        [int_data]  AS (case when [kind]='integer' then CONVERT([int],[data]) end) PERSISTED,
    PRIMARY KEY CLUSTERED 
    (
        [testid] ASC
    ))
    
    
    CREATE UNIQUE NONCLUSTERED INDEX [IX_int_data_filtered] ON [dbo].[testdata]
    (
        [int_data] ASC
    )
    WHERE ([kind]='integer')
    

    Com esta configuração, tentei usar seu procedimento armazenado original para inserir linhas e funcionou mesmo sem OPTION(RECOMPILE).


    Na verdade, parece que a principal razão pela qual a coluna persistida acima funciona é que eu uso CASE. Se eu adicionar CASEà definição de sua visão, o procedimento armazenado funcionará sem OPTION(RECOMPILE).

    create view integer_testdata2 with schemabinding
    as
    select 
        case when a.kind='integer' then CONVERT(int, a.data) end as data
        , a.kind, a.testid
    from dbo.testdata a
    where a.kind = 'integer'
    go
    
    • 6

relate perguntas

  • SQL Server - Como as páginas de dados são armazenadas ao usar um índice clusterizado

  • Preciso de índices separados para cada tipo de consulta ou um índice de várias colunas funcionará?

  • Quando devo usar uma restrição exclusiva em vez de um índice exclusivo?

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Como determinar se um Índice é necessário ou necessário

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve