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 / user-152218

Chessbrain's questions

Martin Hope
Chessbrain
Asked: 2023-04-11 22:11:29 +0800 CST

Compreendendo a comparação do construtor de linha com várias colunas

  • 5

Ao pesquisar o RVC, encontrei a documentação oficial referente aos operadores de comparação, <, >, >=, <=embora esteja claro como:

select (1,2) < (1,3)=true

Devido à fórmula já mencionada na documentação a < c OR (a = c AND b < d), não está tão claro o porquê:

select (1,2,null) < (1,3,0)=true

Para citar a documentação:

Para os casos <, <=, > e >=, os elementos da linha são comparados da esquerda para a direita, parando assim que um par de elementos desigual ou nulo é encontrado.

e

Por exemplo, ROW(1,2,NULL) < ROW(1,3,0) retorna verdadeiro, não nulo, porque o terceiro par de elementos não é considerado.

Qual é o "terceiro par" e como a fórmula é expandida/adaptada para mais e mais colunas (por exemploselect (1,2,3,4,5) < (1,3,0,8,9)

Além disso, por que isso select (1,2,0) >= (1,2,null);retorna nullquando eu esperava truedevido 1>=1ao início.

postgresql
  • 1 respostas
  • 39 Views
Martin Hope
Chessbrain
Asked: 2022-01-20 17:00:31 +0800 CST

Funções SQL dinâmicas imutáveis

  • 0

Cenário 1

Basicamente, digamos que temos uma função que está usando SQL dinâmico, mas também sabemos que ela sempre retornará a mesma saída para a mesma entrada e a declarará imutável será realmente imutável? aka, o compilador/processador de consulta estará ciente desse cenário específico?

De acordo com a documentação oficial

Uma função IMMUTABLE não pode modificar o banco de dados e tem a garantia de retornar os mesmos resultados com os mesmos argumentos para sempre. Esta categoria permite ao otimizador pré-avaliar a função quando uma consulta a chama com argumentos constantes.

Por essa lógica, deve funcionar muito bem, pois se preocupa apenas com a entrada ser a mesma.

Cenário #2

O mesmo que acima, mas o tipo de entrada é anyelementou anyarray. Considerando que SQL é uma linguagem fortemente tipada (de documentos oficiais)

SQL é uma linguagem fortemente tipada. Ou seja, cada item de dados tem um tipo de dados associado que determina seu comportamento e uso permitido.

E saber que anyelementé simplesmente um pseudotipo porque na verdade durante o processamento de funções ele sabe que é (por exemplo) um inteiro ou string. Então, desse ponto de vista, não importa se uma função também aceita anyelementquando é imutável.


Gostaria de saber se o que está escrito acima é de fato o verdadeiro comportamento do PostgreSQL nessas condições. E se houver alguma diferença em comparação com funções imutáveis ​​regulares com SQL regular.

postgresql functions
  • 1 respostas
  • 85 Views
Martin Hope
Chessbrain
Asked: 2021-01-29 07:47:26 +0800 CST

Onde as funções definidas pelo usuário são salvas no PostgreSQL?

  • 0

Para esclarecer o problema que estou tendo, estou escrevendo testes de unidade pgtap no banco de dados e uma das minhas funções retorna uma tabela. No entanto, a função pgtap function_returnsnão possui uma definição para verificação de tabela e suas colunas (nomes e tipos de dados).

Estas são todas as sobrecargas da função:

SELECT function_returns( :schema, :function, :args, :type, :description );
SELECT function_returns( :schema, :function, :args, :type );
SELECT function_returns( :schema, :function, :type, :description );
SELECT function_returns( :schema, :function, :type );
SELECT function_returns( :function, :args, :type, :description );
SELECT function_returns( :function, :args, :type );
SELECT function_returns( :function, :type, :description );
SELECT function_returns( :function, :type );

Você pode ler a definição completa e o que cada parâmetro representa na documentação oficial

Basicamente, o problema é que :typenão funciona para table.

Então eu estou querendo saber onde essas funções definidas pelo usuário são salvas no Postgres (tentando escrever minha própria versão e espero contribuir para o projeto pgtap).

Depois de cavar no código-fonte , encontrei a função usada em segundo plano para verificar isso, é chamada_func_compare

CREATE OR REPLACE FUNCTION _func_compare( NAME, NAME, NAME[], anyelement, anyelement, TEXT)
RETURNS TEXT AS $$
    SELECT CASE WHEN $4 IS NULL
      THEN ok( FALSE, $6 ) || _nosuch($1, $2, $3)
      ELSE is( $4, $5, $6 )
      END;
$$ LANGUAGE SQL;

E não consigo descobrir como o autor estava verificando a definição de retorno válida da função.

postgresql
  • 1 respostas
  • 270 Views
Martin Hope
Chessbrain
Asked: 2021-01-21 03:10:13 +0800 CST

Função timenow() não documentada do PostgreSQL?

  • 1

Olhando para a documentação do PostgreSQL não consegui encontrar nada no timenow(). No entanto, se eu chamar a função, ela funciona.

Então, qual é a diferença entre now()e timenow()?

Eu vou adivinhar que now()é baseado na transação enquanto timenow()é hora do sistema operacional do servidor ou estou completamente fora?

Abaixo está a definição gerada automaticamente pelo DataGrip. Todas as funções do sistema (por exemplo sum) todas têm missing source codee como você pode ver faz parte do pg_catalogesquema.

insira a descrição da imagem aqui

postgresql postgresql-11
  • 1 respostas
  • 299 Views
Martin Hope
Chessbrain
Asked: 2020-07-22 00:36:51 +0800 CST

Quando (ou por que mesmo) usar PLPython(3)u

  • 4

À medida que ganho mais experiência com o PostgreSQL começo a questionar a existência do PLPython. É considerada uma linguagem "não confiável" https://www.postgresql.org/docs/10/plpython.html

O que eu estou querendo saber é, quando ou por que alguém precisaria usar isso? PLPGSQL já é uma linguagem bastante forte que permite fazer muitas coisas. Alguém aqui teve a necessidade de usá-lo, e se sim, para quê?

postgresql plpgsql
  • 2 respostas
  • 1801 Views
Martin Hope
Chessbrain
Asked: 2020-06-13 13:09:07 +0800 CST

Como começar a construir seu próprio SGBD (baseado no PostgreSQL)?

  • 0

Gostaria de aprender a fazer um DBMS (relacional), baseado especificamente no PostgreSQL. Não para fins de produção para fazer um produto comercial, mas para aprender.

Eu planejo usar C++, mas não é exatamente fácil encontrar informações sobre como construir o seu próprio (ou pelo menos por onde começar).

Eu sei que existem pessoas nesta comunidade que são até mesmo contribuidoras do código fonte do PostgreSQL (como Laurenz Albe), então fez sentido fazer essa pergunta aqui.

Tenho acompanhado este curso https://www.youtube.com/playlist?list=PLSE8ODhjZXjbohkNBWQs_otTrBTrjyohi para entender os meandros de um SGBD. Mas como a maioria simplesmente explica o teórico, não tenho a chance de ver o prático ou como realmente fazê-lo.

postgresql dbms
  • 1 respostas
  • 101 Views
Martin Hope
Chessbrain
Asked: 2020-04-15 15:18:38 +0800 CST

Como isso é interpretado pelo PostgreSQL?

  • 1

Apenas para dar um DDL rápido para tornar minha pergunta mais fácil de entender:

------------------ creating tables ------------------
create table if not exists users(
    user_id bigserial primary key,
    first_name text,
    last_name text,
    user_name text
);
create table if not exists managers(
    manager_id bigserial primary key,
    user_id bigint references users(user_id) not null,
    permissions text[]
);
create table if not exists transactions(
    transaction_id bigserial primary key,
    user_id bigint references users(user_id) not null,
    amount numeric,
    is_approved boolean,
    manager_id bigint references managers(manager_id) null
);
------------------ inserting data ------------------
insert into users(first_name, last_name, user_name)
values ('first_name','last_name','ohyea'),
  ('manager','manager','manager');

insert into managers(user_id)
values (2);
insert into transactions(user_id, amount, is_approved, manager_id)
values (1,10,true,null),
  (1,1000,true,1);

Agora, basicamente, obterei o nome do gerente usando desta maneira:

select 
  t.transaction_id,
  t.user_id,
  u.user_name,
  t.amount,
  t.is_approved,
  mu.user_name as manager_name
from transactions t
    join users u on u.user_id = t.user_id
    left join managers m
        join users mu on mu.user_id = m.user_id
    on m.manager_id = t.manager_id;

A parte que me interessa é esta:

    left join managers m
        join users mu on mu.user_id = m.user_id
    on m.manager_id = t.manager_id

O que é isso para o PostgreSQL? Uma suqueria? Tipo, como ele interpreta isso e qual é a diferença entre fazer algo assim e isso:

left join (
    select m.manager_id, u.user_name
    from managers m
        join users u on u.user_id = m.user_id
) mu on mu.manager_id = t.manager_id

EDITAR:

Depois de muitos testes, ambas as abordagens são absolutamente, 100%, 1:1 idênticas. Mesmo plano de execução, mesmos tempos de execução (com pequenas variações de milissegundos), o único benefício que você ganha usando a primeira abordagem é apenas um código mais limpo e mais fácil de seguir em funções maiores com muitas junções de subconsulta.

postgresql
  • 1 respostas
  • 42 Views
Martin Hope
Chessbrain
Asked: 2019-11-05 00:36:46 +0800 CST

DBCC PAGE equivalente no Postgres

  • 3

No SQL Server, você pode verificar informações de índice específicas usando o DBCC PAGEcomando. Existe algo semelhante no postgres?

E se não houver, como você obteria a mesma informação então? Isso é simplesmente para fins de pesquisa.

Este comando retorna isso:

Page @0x00000004ED67A000

m_pageId = (1:299)                  m_headerVersion = 1                 m_type = 1
m_typeFlagBits = 0x0                m_level = 0                         m_flagBits = 0x4
m_objId (AllocUnitId.idObj) = 121   m_indexId (AllocUnitId.idInd) = 256
Metadata: AllocUnitId = 72057594045857792
Metadata: PartitionId = 72057594040614912                                Metadata: IndexId = 1
Metadata: ObjectId = 99             m_prevPage = (1:297)                m_nextPage = (1:300)
pminlen = 4008                      m_slotCnt = 2                       m_freeCnt = 70
m_freeData = 8118                   m_reservedCnt = 0                   m_lsn = (35:184:44)
m_xactReserved = 0                  m_xdesId = (0:0)                    m_ghostRecCnt = 0
m_tornBits = 0                      DB Frag ID = 1

Allocation Status

GAM (1:2) = ALLOCATED               SGAM (1:3) = ALLOCATED 
PFS (1:1) = 0x60 MIXED_EXT ALLOCATED   0_PCT_FULL                        DIFF (1:6) = CHANGED 
ML (1:7) = NOT MIN_LOGGED

Slot 0 Offset 0x60 Length 4011
postgresql index
  • 1 respostas
  • 154 Views
Martin Hope
Chessbrain
Asked: 2019-10-15 23:51:41 +0800 CST

Registrando o id do usuário com a consulta que ele executou

  • 0

Então, estou tentando registrar não apenas o usuário postgres, mas seu ID da minha tabela (por exemplo) Person (person_id) quando ele chama funções.

Até agora, pelo que posso dizer, posso obter quase todas as informações necessárias dessas tabelas do sistema:

  • pg_stat_activity
  • pg_stat_statementsse eu ativá-lo (mas provavelmente não será possível devido a algumas restrições)

Mas a parte que não consigo descobrir é se quero registrar o ID do usuário (por exemplo) da tabela User ( user_idpor exemplo).

Basicamente, eu gostaria de criar uma pequena tabela que abrigaria apenas o log do último mês e inseriria nela.

  • user_id (não id do sistema, mas da minha própria tabela)
  • endereço de IP
  • timestamptz de quando ele chamou a função/consulta
  • consulta que ele executou

Meu principal problema é a parte user_id, já que os outros 3 valores já existem no pg_stat_activity( client_addr, query_start, query)

Se não houver uma maneira fácil de fazer isso acontecer, digamos que eu queira criar uma função que de alguma forma selecionará o user_id com base nos parâmetros retornados por pg_stat_activity, mas não consigo descobrir como eu faria isso. Parâmetros de tabela ocultos como tableoid, cmin, cmax, xmin, xmax, ctidnão me ajudam aqui, pelo menos não vejo como, talvez eu tenha perdido alguma coisa?

postgresql postgresql-11
  • 2 respostas
  • 123 Views
Martin Hope
Chessbrain
Asked: 2019-10-09 00:41:07 +0800 CST

Consulta com desempenho horrível, como corrigir

  • 0
select
    user_id,
    count(id) as unread_count
from
    notifications
where
    is_read = false
    and user_id in(select(unnest('{200 user IDs}' :: bigint[])))
group by
    user_id;

O problema é que essa consulta é executada por 1 minuto e às vezes um pouco mais do que isso. A tabela tem 32 GB e já existe um índice no campo user_id.

Aqui está um plano de execução

HashAggregate  (cost=123354.81..123629.64 rows=27483 width=16) (actual time=90823.880..90823.972 rows=188 loops=1)
  Group Key: user_id
  ->  Nested Loop  (cost=2.32..123217.40 rows=27483 width=16) (actual time=0.184..90752.136 rows=48571 loops=1)
        ->  HashAggregate  (cost=1.76..2.76 rows=100 width=8) (actual time=0.146..0.577 rows=200 loops=1)
              Group Key: unnest(200 user IDs)
              ->  Result  (cost=0.00..0.51 rows=100 width=8) (actual time=0.021..0.073 rows=200 loops=1)
        ->  Index Scan using ix_notification_user_id on notification  (cost=0.56..1229.40 rows=275 width=16) (actual time=119.659..453.533 rows=243 loops=200)
              Index Cond: (200 user IDs)
              Filter: (NOT is_read)
              Rows Removed by Filter: 368
Planning time: 0.189 ms
Execution time: 90824.196 ms

Eu tentei uma solução usando uma tabela temporária, inserindo os valores unnest na tabela temporária e comparando. Mas o desempenho não melhorou em nada.

Eu executei esta consulta para ver as estatísticas do índice:

    schemaname,
    tablename,
    reltuples::bigint,
    relpages::bigint,
    otta,
    round(case when otta = 0 then 0.0 else sml.relpages / otta::numeric end, 1) as tbloat,
    relpages::bigint - otta as wastedpages,
    bs*(sml.relpages-otta)::bigint as wastedbytes,
    pg_size_pretty((bs*(relpages-otta))::bigint) as wastedsize,
    iname,
    ituples::bigint,
    ipages::bigint,
    iotta,
    round(case when iotta = 0 or ipages = 0 then 0.0 else ipages / iotta::numeric end, 1) as ibloat,
    case
        when ipages < iotta then 0
        else ipages::bigint - iotta
    end as wastedipages,
    case
        when ipages < iotta then 0
        else bs*(ipages-iotta)
    end as wastedibytes
    --CASE WHEN ipages < iotta THEN pg_size_pretty(0) ELSE pg_size_pretty((bs*(ipages-iotta))::bigint) END AS wastedisize

    from (
    select
        schemaname,
        tablename,
        cc.reltuples,
        cc.relpages,
        bs,
        ceil((cc.reltuples*((datahdr + ma- (case when datahdr % ma = 0 then ma else datahdr % ma end))+ nullhdr2 + 4))/(bs-20::float)) as otta,
        coalesce(c2.relname, '?') as iname,
        coalesce(c2.reltuples, 0) as ituples,
        coalesce(c2.relpages, 0) as ipages,
        coalesce(ceil((c2.reltuples*(datahdr-12))/(bs-20::float)), 0) as iotta
        -- very rough approximation, assumes all cols

        from (
        select
            ma,
            bs,
            schemaname,
            tablename,
            (datawidth +(hdr + ma-
            (
                case
                when hdr % ma = 0 then ma
                else hdr % ma
            end)))::numeric as datahdr,
            (maxfracsum*(nullhdr + ma-
            (
                case
                when nullhdr % ma = 0 then ma
                else nullhdr % ma
            end))) as nullhdr2
        from
            (
            select
                schemaname,
                tablename,
                hdr,
                ma,
                bs,
                sum((1-null_frac)* avg_width) as datawidth,
                max(null_frac) as maxfracsum,
                hdr +(
                select
                    1 + count(*)/ 8
                from
                    pg_stats s2
                where
                    null_frac <> 0
                    and s2.schemaname = s.schemaname
                    and s2.tablename = s.tablename ) as nullhdr
            from
                pg_stats s,
                (
                select
                    (
                    select
                        current_setting('block_size')::numeric) as bs,
                    case
                        when substring(v, 12, 3) in ('8.0',
                        '8.1',
                        '8.2') then 27
                        else 23
                    end as hdr,
                    case
                        when v ~ 'mingw32' then 8
                        else 4
                    end as ma
                from
                    (
                    select
                        version() as v) as foo ) as constants
            group by
                1,
                2,
                3,
                4,
                5 ) as foo ) as rs
    join pg_class cc on
        cc.relname = rs.tablename
    join pg_namespace nn on
        cc.relnamespace = nn.oid
        and nn.nspname = rs.schemaname
    left join pg_index i on
        indrelid = cc.oid
    left join pg_class c2 on
        c2.oid = i.indexrelid ) as sml
where
    sml.relpages - otta > 0
    or ipages - iotta > 10
order by
    wastedbytes desc,
    wastedibytes desc;

E tanto o índice PK quanto o índice user_id têm mais de 5GB wastedsizee mais de 500k+ wastedpages.

Minha pergunta é, qual a solução para isso? É puramente um problema de índice que precisa reindexou é outra coisa que estou perdendo?

Não tenho permissão para alterar a estrutura da tabela, simplesmente tenho que otimizá-la para, de alguma forma, passar de 1+ minutos para menos de 1s

Depois de adicionar o índice parcial em user_id onde is_read = false, o tempo de consulta foi reduzido em aproximadamente 10 a 15 segundos. Mas obviamente ainda está demorando muito.

EDIT: Há um total de 32,5 milhões de linhas nesta tabela. Executando esta consulta:

SELECT t.user_id, COALESCE(unread_count, 0) AS unread_count
FROM   unnest('{200 user_ids}'::bigint[]) t(user_id)
LEFT   JOIN LATERAL (
   SELECT count(*) AS unread_count
   FROM   notification n
   WHERE  n.user_id = t.user_id
   AND    n.is_read = false
   ) sub ON true
;     

resulta neste plano de execução (engraçado, ontem isso durou mais de um minuto, hoje por ~ 30 segundos ou menos):

Nested Loop Left Join  (cost=1209.05..120908.50 rows=100 width=16) (actual time=333.088..27260.557 rows=200 loops=1)
  Buffers: shared hit=1981 read=20396 dirtied=7
  I/O Timings: read=27023.896
  ->  Function Scan on unnest t  (cost=0.00..1.00 rows=100 width=8) (actual time=0.022..0.360 rows=200 loops=1)
  ->  Aggregate  (cost=1209.04..1209.05 rows=1 width=8) (actual time=136.292..136.293 rows=1 loops=200)
        Buffers: shared hit=1981 read=20396 dirtied=7
        I/O Timings: read=27023.896
        ->  Index Only Scan using ix_test on notification n  (cost=0.44..1208.29 rows=300 width=0) (actual time=2.153..136.170 rows=105 loops=200)
              Index Cond: (user_id = t.user_id)
              Heap Fetches: 21088
              Buffers: shared hit=1981 read=20396 dirtied=7
              I/O Timings: read=27023.896
Planning time: 0.135 ms
Execution time: 27260.745 ms
postgresql optimization
  • 2 respostas
  • 155 Views
Martin Hope
Chessbrain
Asked: 2019-09-12 07:58:11 +0800 CST

erro de sintaxe em ou próximo a "current_timestamp" ao criar a tabela de partição

  • 1

Estou tentando criar uma partição nos últimos 30 dias. No entanto, quando executo este código:

create table Test_Older30day partition of Test
    for values from (current_timestamp + interval'-30 day') to (current_timestamp);

Eu recebo este erro:

syntax error at or near "current_timestamp"

Estou confuso, o que estou fazendo de errado aqui?

a tabela fica assim:

create table if not exists Test(
source_name varchar,
event_name varchar,
service_data json,
stamp timestamptz
)partition by range(stamp);

os tipos de dados correspondem e eu usei a partição por intervalo no campo de data.

Já sei que posso inseri-los manualmente

create table Test_Older30day partition of Test
        for values from ('2019-08-11') to ('2019-09-11')

Curtiu isso. O que estou tentando tentar é uma maneira mais automatizada de fazer isso. Basicamente, a ideia é evitar digitá-lo todos os meses ou semanas. Apenas para executar a consulta e usaria a data atual.

postgresql partitioning
  • 1 respostas
  • 1581 Views
Martin Hope
Chessbrain
Asked: 2019-09-11 15:41:16 +0800 CST

Maneira mais eficiente de inserir dados na tabela de arquivamento sem influenciar a produção?

  • 1

Por exemplo, digamos que temos a tabela A:

create table if not exists T(
column1 int,
column2 varchar,
column3 date
);

e tabela de arquivamento TArchive:

create table if not exists TArchive(
column1 int,
column2 varchar,
column3 date
);

Qual seria a melhor abordagem para inserir dados anteriores à xdata no TArchive sem bloquear a tabela T na produção? Sob a suposição de que a tabela T tem uma grande quantidade de linhas.

Estou pesquisando isso há horas. No SQL Server você tem diferentes abordagens como: https://www.brentozar.com/archive/2018/04/how-to-delete-just-some-rows-from-a-really-big-table/ Mas no PostgreSQL Eu mal consigo encontrar nada.

Você deve apenas pegar os dados diretamente da tabela T e importá-los para o TArchive?

Você deve importar seus dados para uma tabela temporária primeiro e depois importá-los para a tabela de arquivamento? E se sim, por que essa abordagem seria melhor quando você está fazendo 2x as inserções para os mesmos dados.

Quantas funções você deve fazer? Uma função para governá-los todos? Ou uma função para arquivamento e outra para deletar os dados antigos?

Existem outras abordagens?

postgresql performance
  • 3 respostas
  • 570 Views
Martin Hope
Chessbrain
Asked: 2019-09-07 04:37:03 +0800 CST

Existe uma coluna nomeada na tabela mas não pode ser referenciada a partir desta parte da consulta

  • 0

Estou aprendendo Postgres (vindo do SQL Server), e esse erro realmente me confunde.

Aqui está o código com alguns dados de exemplo:

create table T (
ID serial primary key,
A varchar(1),
B varchar(1),
C varchar(1)
)

↑ Tabela de testes.

insert into T (A, B, C)
values('A', 'B', 'C'), ('A', 'B', 'C')

↑ Inserir duplicatas

delete from T
where ID in (
    select t.ID
    from (  select ID, row_number() over (partition by A,B,C order by A,B,C) as rn
            from T) as t
    where t.rn < (select max(t.rn) from t)
    )

↑ Excluir duplicata mantendo a última entrada.

O problema está no (select max(t.rn) from t)que estou assumindo que este é um erro noob relacionado a não conhecer a sintaxe do postgres quando se trata de referenciar colunas com aliases?

postgresql subquery
  • 1 respostas
  • 11553 Views
Martin Hope
Chessbrain
Asked: 2019-07-30 09:13:46 +0800 CST

Obtendo Index Scan em vez de uma possível Busca de Índice?

  • 4

Atualmente aprendendo algumas coisas sobre otimização de consultas, e tenho tentado consultas diferentes e me deparei com esse "problema".

Estou usando o banco de dados AdventureWorks2014, executei esta consulta simples:

estrutura da tabela (retirada de https://www.sqldatadictionary.com/AdventureWorks2014.pdf ):

insira a descrição da imagem aqui

SELECT C.CustomerID
FROM Sales.Customer AS C
WHERE C.CustomerID > 100

retorna 19.720 linhas

número total de linhas em Sales.Customer = 19.820

E depois de verificar se CustomerID não é apenas o PK da tabela, mas também tem um índice clusterizado (ainda que usa um índice não clusterizado), esse é o caso:

EXEC SP_HELPINDEX 'Sales.Customer'

insira a descrição da imagem aqui

Aqui está o plano de execução ↓

https://www.brentozar.com/pastetheplan/?id=B1g1SihGr

Eu li que quando confrontado com grandes quantidades de dados e/ou quando ele retorna mais de 50% do conjunto de dados, o otimizador de consulta favorecerá uma verificação de índice. Mas essa tabela como um todo mal tem 20.000 linhas (19.820 para ser exato), não é uma tabela grande de forma alguma.

Quando executo esta consulta:

SELECT C.CustomerID
FROM Sales.Customer AS C
WHERE C.CustomerID > 30000

retorna 118 linhas

https://www.brentozar.com/pastetheplan/?id=Byyux32MS

Em vez disso, recebo uma busca de índice, então pensei que era devido a esse "caso de mais de 50%", no entanto, também executei esta consulta:

SELECT C.CustomerID
FROM Sales.Customer AS C
WHERE C.CustomerID > 20000

retorna 10.118 linhas

https://www.brentozar.com/pastetheplan/?id=HJ9oV33zr

E também usou uma busca de índice, embora estivesse retornando mais de 50% do conjunto de dados.

Então o que está acontecendo aqui?

EDITAR:

Com as Estatísticas de E/S ativadas, a consulta >100 retorna:

Table 'Customer'. Scan count 1, logical reads 37, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Enquanto o > 20.000 retornou:

Table 'Customer'. Scan count 1, logical reads 65, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Então, adicionei WITH(FORCESCAN)a opção > 20.000 para ver o que aconteceria:

Table 'Customer'. Scan count 1, logical reads 37, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

Portanto, ele acaba funcionando melhor com um Index Scan (leituras menos lógicas), mesmo que o otimizador de consulta tenha escolhido executar um Index Seek para essa consulta específica.

sql-server index
  • 3 respostas
  • 5132 Views
Martin Hope
Chessbrain
Asked: 2019-07-09 15:02:34 +0800 CST

Resultado de saída como 2 colunas separadas

  • 0

Então criei um procedimento que calcula a média e a mediana de um array de strings de números:

CREATE PROCEDURE dbo.spAvg_Median 
    @input nvarchar(20) 
AS
BEGIN
    declare @split table(id int primary key identity (1,1), number int)

    INSERT INTO @split SELECT value FROM string_split(@input, ',')

    SELECT Average FROM (
        SELECT SUM(number)/COUNT(number) as [Average]
        FROM @split
        ) AS T1
    UNION
    SELECT Median FROM (
        SELECT o.number AS [Median], rn=ROW_NUMBER() OVER (ORDER BY o.number), c.c
        FROM @split AS o
        CROSS APPLY (SELECT c=COUNT(*) FROM @split b) AS c
        ) AS x
        WHERE rn IN ((c + 1)/2, (c + 2)/2)
END
RETURN 0 
GO

No entanto, quando você executa essa consulta, obtém o seguinte resultado:

EXEC dbo.spAvg_Median'1,5,9,8,7'

insira a descrição da imagem aqui

O que eu quero que ele produza é Média em uma coluna e Mediana em outra coluna próxima a ela.

O comando UNION está lá para que ele não o produza como duas consultas diferentes como esta, pois não é isso que eu quero: insira a descrição da imagem aqui

stored-procedures sql-server-2017
  • 1 respostas
  • 25 Views
Martin Hope
Chessbrain
Asked: 2018-12-16 11:16:17 +0800 CST

Como dividir a matriz XML em linhas separadas (enquanto mantém a consistência)

  • 6

Estou trabalhando no dump do banco de dados desta seção exata de troca de pilha. Enquanto estou trabalhando nisso, encontrei um problema que atualmente não consigo resolver.

No arquivo XML Posts.xml o conteúdo fica assim

insira a descrição da imagem aqui

É claro que existem várias linhas, mas é assim que se parece. Já existe um arquivo Tags.xml fornecido no dump, o que torna ainda mais óbvio que o atributo "Tags" nessa imagem é de fato sua tabela separada (muitos para muitos).

Então, agora estou tentando descobrir uma maneira de extrair as tags. Aqui está o que eu tentei fazer:

CREATE TABLE #TestingIdea (
Id int PRIMARY KEY IDENTITY (1,1),
PostId int NULL,
Tag nvarchar (MAX) NULL
)
GO

↑ A tabela que criei para testar meu código. Já preenchi com as Tags e PostIds

SELECT  T1.PostId,
        S.SplitTag
FROM (
    SELECT  T.PostId, 
            cast('<X>'+ REPLACE(T.Tag,'>','</X><X>') + '</X>' as XML) AS NewTag
    FROM #TestingIdea AS T
    ) AS T1
CROSS APPLY (
    SELECT tData.value('.','nvarchar(30)') SplitTag
    FROM T1.NewTag.nodes('X') AS T(tData)
    ) AS S
GO

Ainda este código retorna este erro

XML parsing: line 1, character 37, illegal qualified name character

Depois de pesquisar esse erro (incluindo aqui), o que quer que as pessoas tivessem (como marcas " extras ou conjuntos de CHAR diferentes) eu não tinha. Então estou meio travado. Talvez eu tenha perdido algo extremamente óbvio nas respostas anteriores, encontrei T_T Em qualquer caso Agradeço qualquer ajuda e conselhos sobre como resolver isso. É a última tabela que ainda não normalizei.

Pequenos dados de amostra do arquivo XML https://pastebin.com/AW0Z8Be2 Para qualquer pessoa interessada no programa eu uso para visualizar arquivos XML (assim é muito mais fácil de ler como na imagem acima). Chama-se FOXE XML Reader (Free XML Editor - First Object)

sql-server sql-server-2017
  • 1 respostas
  • 3199 Views

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