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 / 问题

All perguntas(dba)

Martin Hope
Hannah Vernon
Asked: 2013-09-29 17:56:23 +0800 CST

As chaves naturais fornecem desempenho superior ou inferior no SQL Server do que chaves inteiras substitutas?

  • 28

Sou fã de chaves substitutas. Existe o risco de minhas descobertas serem tendenciosas de confirmação.

Muitas perguntas que vi aqui e em http://stackoverflow.com usam chaves naturais em vez de chaves substitutas com base em IDENTITY()valores.

Minha experiência em sistemas de computador me diz que executar qualquer operação comparativa em um número inteiro será mais rápido do que comparar strings.

Esse comentário me fez questionar minhas crenças, então pensei em criar um sistema para investigar minha tese de que inteiros são mais rápidos que strings para uso como chaves no SQL Server.

Como é provável que haja muito pouca diferença perceptível em pequenos conjuntos de dados, pensei imediatamente em uma configuração de duas tabelas em que a tabela primária tem 1.000.000 linhas e a tabela secundária tem 10 linhas para cada linha na tabela primária para um total de 10.000.000 linhas em a tabela secundária. A premissa do meu teste é criar dois conjuntos de tabelas como este, um usando chaves naturais e outro usando chaves inteiras, e executar testes de tempo em uma consulta simples como:

SELECT *
FROM Table1
    INNER JOIN Table2 ON Table1.Key = Table2.Key;

O seguinte é o código que criei como uma cama de teste:

USE Master;
IF (SELECT COUNT(database_id) FROM sys.databases d WHERE d.name = 'NaturalKeyTest') = 1
BEGIN
    ALTER DATABASE NaturalKeyTest SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
    DROP DATABASE NaturalKeyTest;
END
GO
CREATE DATABASE NaturalKeyTest 
    ON (NAME = 'NaturalKeyTest', FILENAME = 
        'C:\SQLServer\Data\NaturalKeyTest.mdf', SIZE=8GB, FILEGROWTH=1GB) 
    LOG ON (NAME='NaturalKeyTestLog', FILENAME = 
        'C:\SQLServer\Logs\NaturalKeyTest.mdf', SIZE=256MB, FILEGROWTH=128MB);
GO
ALTER DATABASE NaturalKeyTest SET RECOVERY SIMPLE;
GO
USE NaturalKeyTest;
GO
CREATE VIEW GetRand
AS 
    SELECT RAND() AS RandomNumber;
GO
CREATE FUNCTION RandomString
(
    @StringLength INT
)
RETURNS NVARCHAR(max)
AS
BEGIN
    DECLARE @cnt INT = 0
    DECLARE @str NVARCHAR(MAX) = '';
    DECLARE @RandomNum FLOAT = 0;
    WHILE @cnt < @StringLength
    BEGIN
        SELECT @RandomNum = RandomNumber
        FROM GetRand;
        SET @str = @str + CAST(CHAR((@RandomNum * 64.) + 32) AS NVARCHAR(MAX)); 
        SET @cnt = @cnt + 1;
    END
    RETURN @str;
END;
GO
CREATE TABLE NaturalTable1
(
    NaturalTable1Key NVARCHAR(255) NOT NULL 
        CONSTRAINT PK_NaturalTable1 PRIMARY KEY CLUSTERED 
    , Table1TestData NVARCHAR(255) NOT NULL 
);
CREATE TABLE NaturalTable2
(
    NaturalTable2Key NVARCHAR(255) NOT NULL 
        CONSTRAINT PK_NaturalTable2 PRIMARY KEY CLUSTERED 
    , NaturalTable1Key NVARCHAR(255) NOT NULL 
        CONSTRAINT FK_NaturalTable2_NaturalTable1Key 
        FOREIGN KEY REFERENCES dbo.NaturalTable1 (NaturalTable1Key) 
        ON DELETE CASCADE ON UPDATE CASCADE
    , Table2TestData NVARCHAR(255) NOT NULL  
);
GO

/* insert 1,000,000 rows into NaturalTable1 */
INSERT INTO NaturalTable1 (NaturalTable1Key, Table1TestData) 
    VALUES (dbo.RandomString(25), dbo.RandomString(100));
GO 1000000 

/* insert 10,000,000 rows into NaturalTable2 */
INSERT INTO NaturalTable2 (NaturalTable2Key, NaturalTable1Key, Table2TestData)
SELECT dbo.RandomString(25), T1.NaturalTable1Key, dbo.RandomString(100)
FROM NaturalTable1 T1
GO 10 

CREATE TABLE IDTable1
(
    IDTable1Key INT NOT NULL CONSTRAINT PK_IDTable1 
    PRIMARY KEY CLUSTERED IDENTITY(1,1)
    , Table1TestData NVARCHAR(255) NOT NULL 
    CONSTRAINT DF_IDTable1_TestData DEFAULT dbo.RandomString(100)
);
CREATE TABLE IDTable2
(
    IDTable2Key INT NOT NULL CONSTRAINT PK_IDTable2 
        PRIMARY KEY CLUSTERED IDENTITY(1,1)
    , IDTable1Key INT NOT NULL 
        CONSTRAINT FK_IDTable2_IDTable1Key FOREIGN KEY 
        REFERENCES dbo.IDTable1 (IDTable1Key) 
        ON DELETE CASCADE ON UPDATE CASCADE
    , Table2TestData NVARCHAR(255) NOT NULL 
        CONSTRAINT DF_IDTable2_TestData DEFAULT dbo.RandomString(100)
);
GO
INSERT INTO IDTable1 DEFAULT VALUES;
GO 1000000
INSERT INTO IDTable2 (IDTable1Key)
SELECT T1.IDTable1Key
FROM IDTable1 T1
GO 10

O código acima cria um banco de dados e 4 tabelas, e preenche as tabelas com dados, prontos para teste. O código de teste que executei é:

USE NaturalKeyTest;
GO
DECLARE @loops INT = 0;
DECLARE @MaxLoops INT = 10;
DECLARE @Results TABLE (
    FinishedAt DATETIME DEFAULT (GETDATE())
    , KeyType NVARCHAR(255)
    , ElapsedTime FLOAT
);
WHILE @loops < @MaxLoops
BEGIN
    DBCC FREEPROCCACHE;
    DBCC FREESESSIONCACHE;
    DBCC FREESYSTEMCACHE ('ALL');
    DBCC DROPCLEANBUFFERS;
    WAITFOR DELAY '00:00:05';
    DECLARE @start DATETIME = GETDATE();
    DECLARE @end DATETIME;
    DECLARE @count INT;
    SELECT @count = COUNT(*) 
    FROM dbo.NaturalTable1 T1
        INNER JOIN dbo.NaturalTable2 T2 ON T1.NaturalTable1Key = T2.NaturalTable1Key;
    SET @end = GETDATE();
    INSERT INTO @Results (KeyType, ElapsedTime)
    SELECT 'Natural PK' AS KeyType, CAST((@end - @start) AS FLOAT) AS ElapsedTime;

    DBCC FREEPROCCACHE;
    DBCC FREESESSIONCACHE;
    DBCC FREESYSTEMCACHE ('ALL');
    DBCC DROPCLEANBUFFERS;
    WAITFOR DELAY '00:00:05';
    SET @start = GETDATE();
    SELECT @count = COUNT(*) 
    FROM dbo.IDTable1 T1
        INNER JOIN dbo.IDTable2 T2 ON T1.IDTable1Key = T2.IDTable1Key;
    SET @end = GETDATE();
    INSERT INTO @Results (KeyType, ElapsedTime)
    SELECT 'IDENTITY() PK' AS KeyType, CAST((@end - @start) AS FLOAT) AS ElapsedTime;

    SET @loops = @loops + 1;
END
SELECT KeyType, FORMAT(CAST(AVG(ElapsedTime) AS DATETIME), 'HH:mm:ss.fff') AS AvgTime 
FROM @Results
GROUP BY KeyType;

Estes são os resultados:

insira a descrição da imagem aqui

Estou fazendo algo errado aqui ou as teclas INT são 3 vezes mais rápidas que as teclas naturais de 25 caracteres?

Observe que escrevi uma pergunta complementar aqui .

sql-server sql-server-2012
  • 3 respostas
  • 5380 Views
Martin Hope
cubetwo1729
Asked: 2013-06-25 05:50:45 +0800 CST

Como escrever uma consulta que encontra todas as referências circulares quando uma tabela faz referência a si mesma?

  • 28

Tenho o seguinte esquema (nomes alterados), que não posso alterar:

CREATE TABLE MyTable (
    Id INT NOT NULL PRIMARY KEY,
    ParentId INT NOT NULL
);

ALTER TABLE MyTable ADD FOREIGN KEY (ParentId) REFERENCES MyTable(Id);

Ou seja, cada registro é filho de outro registro. Se um registro ParentIdfor igual ao seu Id, o registro será considerado um nó raiz.

Eu quero executar a consulta que encontrará todas as referências circulares. Por exemplo, com os dados

INSERT INTO MyTable (Id, ParentId) VALUES
    (0, 0),
    (1, 0),
    (2, 4),
    (3, 2),
    (4, 3);

a consulta deve retornar

Id | Cycle
2  | 2 < 4 < 3 < 2
3  | 3 < 2 < 4 < 3
4  | 4 < 3 < 2 < 4

Escrevi a seguinte consulta para o SQL Server 2008 R2 e gostaria de saber se essa consulta pode ser melhorada:

IF OBJECT_ID(N'tempdb..#Results') IS NOT NULL DROP TABLE #Results;
CREATE TABLE #Results (Id INT, HasParentalCycle BIT, Cycle VARCHAR(MAX));

DECLARE @i INT,
    @j INT,
    @flag BIT,
    @isRoot BIT,
    @ids VARCHAR(MAX);

DECLARE MyCursor CURSOR FAST_FORWARD FOR
    SELECT Id
    FROM MyTable;

OPEN MyCursor;
FETCH NEXT FROM MyCursor INTO @i;
WHILE @@FETCH_STATUS = 0
BEGIN
    IF OBJECT_ID(N'tempdb..#Parents') IS NOT NULL DROP TABLE #Parents;
    CREATE TABLE #Parents (Id INT);

    SET @ids = NULL;
    SET @isRoot = 0;
    SET @flag = 0;
    SET @j = @i;
    INSERT INTO #Parents (Id) VALUES (@j);

    WHILE (1=1)
    BEGIN
        SELECT
            @j = ParentId,
            @isRoot = CASE WHEN ParentId = Id THEN 1 ELSE 0 END
        FROM MyTable
        WHERE Id = @j;

        IF (@isRoot = 1)
        BEGIN
            SET @flag = 0;
            BREAK;
        END        

        IF EXISTS (SELECT 1 FROM #Parents WHERE Id = @j)
        BEGIN
            INSERT INTO #Parents (Id) VALUES (@j);
            SET @flag = 1;
            SELECT @ids = COALESCE(@ids + ' < ', '') + CAST(Id AS VARCHAR) FROM #Parents;
            BREAK;
        END
        ELSE
        BEGIN
            INSERT INTO #Parents (Id) VALUES (@j);
        END        
    END

    INSERT INTO #Results (Id, HasParentalCycle, Cycle) VALUES (@i, @flag, @ids);

    FETCH NEXT FROM MyCursor INTO @i;
END
CLOSE MyCursor;
DEALLOCATE MyCursor;

SELECT Id, Cycle
FROM #Results
WHERE HasParentalCycle = 1;
sql-server sql-server-2008-r2
  • 2 respostas
  • 26610 Views
Martin Hope
Mourya
Asked: 2012-11-09 21:24:51 +0800 CST

Por que precisamos reconstruir e reorganizar índices no SQL Server

  • 28

Depois de pesquisar na internet não consegui encontrar o motivo

  1. Por que precisamos reconstruir e reorganizar índices no SQL Server?

  2. o que acontece internamente quando reconstruímos e reorganizamos?

Um artigo em um site diz:

O índice deve ser reconstruído quando a fragmentação do índice for maior que 40%. O índice deve ser reorganizado quando a fragmentação do índice estiver entre 10% e 40%. O processo de reconstrução de índice usa mais CPU e bloqueia os recursos do banco de dados. A versão de desenvolvimento do SQL Server e a versão Enterprise possuem a opção ONLINE, que pode ser ativada quando o Index é reconstruído. A opção ONLINE manterá o índice disponível durante a reconstrução.

Não consegui entender isso, embora diga que WHENpara fazer isso, mas gostaria de saber WHYse precisamos reconstruir e reorganizar os índices?

sql-server sql-server-2008
  • 2 respostas
  • 35578 Views
Martin Hope
ivanmp
Asked: 2012-10-19 03:56:17 +0800 CST

Onde as estatísticas são armazenadas fisicamente no SQL Server?

  • 28

Onde estão as estatísticas usadas pelo Query Optimizer armazenadas fisicamente dentro de um arquivo de banco de dados do SQL Server e do Buffer Pool?

Mais especificamente, existe uma maneira de descobrir as páginas usadas pelas estatísticas usando DMVs e/ou DBCC?

Eu possuo os livros SQL Server 2008 Internals e SQL Server Internals and Troubleshooting e nenhum deles fala sobre a estrutura física das estatísticas; se o fizerem, não conseguirei encontrar essa informação.

sql-server statistics
  • 1 respostas
  • 4737 Views
Martin Hope
Timka
Asked: 2012-06-22 09:13:11 +0800 CST

Como definir o banco de dados Postgresql para ver a data como "MDY" permanentemente

  • 28

Como posso definir meu banco de dados para ver a 'data' como "MDY" sem executar:

SET datestyle = "ISO, MDY";

toda vez que estou tentando acessá-lo? Estou usando o Postgresql versão 9.1, Ubuntu 12.04. A localidade do meu sistema, no momento da instalação do banco de dados, foi definida como en_CA.utf8e recentemente mudei para en_US.utf8.

show lc_CTYPE

retorna: -->"en_CA.UTF-8"

mas

show LC_CoLLATE

retorna: -->"en_CA.UTF-8"

postgresql date-format
  • 3 respostas
  • 60690 Views
Martin Hope
RK Kuppala
Asked: 2012-03-15 07:34:32 +0800 CST

Como obtenho uma lista de todas as tabelas particionadas no meu banco de dados?

  • 28

Como obtenho uma lista de todas as tabelas particionadas no meu banco de dados?

Quais tabelas de sistema/DMVs devo examinar?

sql-server sql-server-2008
  • 4 respostas
  • 137302 Views
Martin Hope
MatthewMartin
Asked: 2011-11-29 10:40:02 +0800 CST

O que é o nível de isolamento "Caos" e quando deve ser usado?

  • 28

A documentação do ADO.NET mostra a possibilidade de definir o nível de transação para uma transação SQL como Caos. Parece desagradável, mas se o recurso estiver lá, presumivelmente tem algum uso legítimo.

O comando SET TRANSACTION ISOLATION LEVEL em BOL (ah! Veja, eu posso usar google e BOL) nada parece ser chamado de "caos" e o ADO.NET tem 5 modos que correspondem perfeitamente aos níveis documentados, além de "caos"

Para que ou para quem é esse nível de Caos? (E por que tem um nome nada amigável?)

Refs: A enumeração ADO.NET

sql-server transaction
  • 3 respostas
  • 15034 Views
Martin Hope
quanta
Asked: 2011-09-26 20:24:47 +0800 CST

Qual é a maneira mais segura de mudar o formato do log binário em tempo de execução?

  • 28

Devido ao seguinte aviso em mysqld.log:

[Aviso] Instrução não segura gravada no log binário usando o formato de instrução desde BINLOG_FORMAT = STATEMENT. A instrução não é segura porque usa uma cláusula LIMIT. Isso não é seguro porque o conjunto de linhas incluído não pode ser previsto.

Eu quero mudar o formato de replicação para MIXED.

Mas de acordo com o documento MySQL:

Alternar o formato de replicação em tempo de execução não é recomendado quando existem tabelas temporárias, porque as tabelas temporárias são registradas apenas ao usar a replicação baseada em instrução, enquanto na replicação baseada em linha elas não são registradas.

Então, a questão é como posso identificar se existem tabelas temporárias para alternar o formato de log binário com segurança?

mysql replication
  • 2 respostas
  • 50012 Views
Martin Hope
David Eyk
Asked: 2011-08-10 15:04:10 +0800 CST

Como criar um índice para acelerar uma consulta LIKE agregada em uma expressão?

  • 28

Posso estar fazendo a pergunta errada no título. Aqui estão os fatos:

Meu pessoal de atendimento ao cliente tem reclamado dos tempos de resposta lentos ao fazer pesquisas de clientes na interface de administração do nosso site baseado em Django.

Estamos usando o Postgres 8.4.6. Comecei a registrar consultas lentas e descobri este culpado:

SELECT COUNT(*) FROM "auth_user" WHERE UPPER("auth_user"."email"::text) LIKE UPPER(E'%deyk%')

Esta consulta está demorando mais de 32 segundos para ser executada. Aqui está o plano de consulta fornecido pelo EXPLAIN:

QUERY PLAN
Aggregate  (cost=205171.71..205171.72 rows=1 width=0)
  ->  Seq Scan on auth_user  (cost=0.00..205166.46 rows=2096 width=0)
        Filter: (upper((email)::text) ~~ '%DEYK%'::text)

Como esta é uma consulta gerada pelo Django ORM a partir de um Django QuerySet gerado pelo aplicativo Django Admin, não tenho nenhum controle sobre a consulta em si. Um índice parece ser a solução lógica. Eu tentei criar um índice para acelerar isso, mas não fez diferença:

CREATE INDEX auth_user_email_upper ON auth_user USING btree (upper(email::text))

O que estou fazendo errado? Como posso acelerar esta consulta?

postgresql performance
  • 2 respostas
  • 28239 Views
Martin Hope
anon
Asked: 2011-07-25 19:18:25 +0800 CST

Quais são algumas práticas recomendadas para usar esquemas no SQL Server?

  • 28

Entendo os recursos dos esquemas do SQL Server, mas quais são as práticas recomendadas? Claro que eles oferecem outra camada de segurança e fornecem agrupamento lógico de objetos de banco de dados dentro do banco de dados, mas o que é típico lá fora? Muitas vezes, em minha experiência, não vejo muitos esquemas personalizados utilizados. Isso é típico? É o cenário menos frequente em que os esquemas personalizados devem ser usados?

sql-server sql-server-2008
  • 3 respostas
  • 20243 Views
Prev
Próximo

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