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-196980

Hasan Can Saral's questions

Martin Hope
Hasan Can Saral
Asked: 2025-03-27 20:27:24 +0800 CST

Como o PostgreSQL usa meu índice composto sem a coluna do meio na consulta?

  • 5

Tenho a seguinte tabela:

CREATE TABLE transactions
(
    id                                    NUMERIC(20, 0)                           NOT NULL DEFAULT NEXTVAL('transactions_sequence') PRIMARY KEY,
    transaction_date                      TIMESTAMP      DEFAULT NULL              NULL,
    transaction_type                      VARCHAR(255)   DEFAULT NULL              NULL,
    merchant_id                           VARCHAR(255)   DEFAULT NULL              NULL,
    transaction_type                      VARCHAR(255)   DEFAULT NULL              NULL,
    -- Some more columns here
);

e o seguinte índice:

CREATE INDEX transactions_merchant_id_idx ON transactions (merchant_id, transaction_type, transaction_date DESC, id) WHERE merchant_id IS NOT NULL;

Tenho as seguintes dúvidas:

SELECT id, transaction_date
FROM transactions
WHERE merchant_id = 'some_merchant_id'
  AND transaction_type = 'a'
  AND transaction_date >= '2025-01-01'
  AND transaction_date < '2025-03-28'
ORDER BY transaction_date DESC
LIMIT 100

Essa consulta funciona perfeitamente e eu obtenho apenas uma varredura de índice:

Limit  (cost=0.29..7.47 rows=1 width=13) (actual time=1.119..1.120 rows=0 loops=1)
  ->  Index Scan using transactions_transaction_type_idx on transactions  (cost=0.29..7.47 rows=1 width=13) (actual time=1.118..1.118 rows=0 loops=1)
        Index Cond: (((transaction_type)::text = 'a'::text) AND (transaction_date >= '2025-01-01 00:00:00'::timestamp without time zone) AND (transaction_date < '2025-03-28 00:00:00'::timestamp without time zone))
        Filter: ((merchant_id)::text = 'some_merchant_id'::text)
Planning Time: 0.311 ms
Execution Time: 1.139 ms

No entanto, quando preciso de transaction_typeresultados independentes com:

SELECT id, transaction_date
FROM transactions
WHERE merchant_id = 'some_merchant_id'
  AND transaction_date >= '2025-01-01'
  AND transaction_date < '2025-03-28'
ORDER BY transaction_date DESC
LIMIT 100

Ainda recebo apenas a varredura de índice:

Limit  (cost=38.08..38.19 rows=44 width=13) (actual time=0.108..0.115 rows=47 loops=1)
  ->  Sort  (cost=38.08..38.19 rows=44 width=13) (actual time=0.107..0.110 rows=47 loops=1)
        Sort Key: transaction_date DESC
        Sort Method: quicksort  Memory: 27kB
        ->  Index Only Scan using transactions_merchant_id_idx on transactions  (cost=0.29..36.88 rows=44 width=13) (actual time=0.029..0.093 rows=47 loops=1)
              Index Cond: ((merchant_id = 'some_merchant_id'::text) AND (transaction_date >= '2025-01-01 00:00:00'::timestamp without time zone) AND (transaction_date < '2025-03-28 00:00:00'::timestamp without time zone))
              Heap Fetches: 0
Planning Time: 0.228 ms
Execution Time: 0.161 ms

Eu tenho uma lista de todos os valores potenciais de transaction_type, então inicialmente pensei que isso seria melhor:

SELECT id, transaction_date
FROM transactions
WHERE merchant_id = 'some_merchant_id'
  AND transaction_type IN ('a', 'b', 'c', ...) -- all the potential values here
  AND transaction_date >= '2025-01-01'
  AND transaction_date < '2025-03-28'
ORDER BY transaction_date DESC
LIMIT 100

mas em vez disso, dependendo do número de valores na INcláusula, posso obter um adicional filterno plano de consulta:

Limit  (cost=38.29..38.40 rows=43 width=13) (actual time=0.110..0.118 rows=47 loops=1)
  ->  Sort  (cost=38.29..38.40 rows=43 width=13) (actual time=0.109..0.112 rows=47 loops=1)
        Sort Key: transaction_date DESC
        Sort Method: quicksort  Memory: 27kB
        ->  Index Only Scan using transactions_merchant_id_idx on transactions  (cost=0.31..37.13 rows=43 width=13) (actual time=0.030..0.097 rows=47 loops=1)
              Index Cond: ((merchant_id = 'some_merchant_id'::text) AND (transaction_date >= '2025-01-01 00:00:00'::timestamp without time zone) AND (transaction_date < '2025-03-28 00:00:00'::timestamp without time zone))
"              Filter: ((transaction_type)::text = ANY ('{a,b,c,d,e,f}'::text[]))"
              Heap Fetches: 0
Planning Time: 0.340 ms
Execution Time: 0.142 ms

Então, mesmo se eu pular a transaction_typecoluna do meio, meu índice é usado. Mas com qual consulta eu sou melhor, com IN on transaction_typecom todos os valores potenciais ou sem nem mesmo o filtro? Como meu índice ainda é usado sem o filtro on transaction_type?

postgresql
  • 1 respostas
  • 25 Views
Martin Hope
Hasan Can Saral
Asked: 2025-02-24 13:12:05 +0800 CST

Índice de expressão com função definida pelo usuário não usada na consulta

  • 7

Tenho a seguinte tabela:

CREATE TABLE users (
 first_name VARCHAR(256)  DEFAULT NULL NULL,
 last_name  VARCHAR(256)  DEFAULT NULL NULL,
 full_name  VARCHAR(1024) GENERATED ALWAYS AS
        (CASE
             WHEN first_name IS NULL AND
                  last_name IS NULL THEN NULL
             ELSE
                 (TRIM(COALESCE(first_name, '') || ' ' || COALESCE(last_name, ''))) END) STORED;
);

E tenho a seguinte função para "normalizar":

CREATE OR REPLACE FUNCTION NORMALIZE_FUNC(IN source VARCHAR)
    RETURNS VARCHAR
    LANGUAGE PLPGSQL
AS
$$
BEGIN

    source := (SELECT COALESCE(source, ''));

    source := (SELECT REPLACE(
                      REPLACE(
                      REPLACE(
                      REPLACE(
                      REPLACE(
                      REPLACE(
                      LOWER(source),
                      'ş', 's'),
                      'ç', 'c'),
                      'ı', 'i'),
                      'ü', 'u'),
                      'ö', 'o'),
                      'ğ', 'g'))::VARCHAR;

    RETURN source;

END
$$
IMMUTABLE;

e o seguinte índice e consulta, soundex()de onde é a fuzzystrmatchextensão:

CREATE INDEX users_full_name_soundex_idx ON users (SOUNDEX(NORMALIZE_FUNC(full_name))) WHERE full_name IS NOT NULL;

SELECT *
FROM users
WHERE SOUNDEX(NORMALIZE_FUNC(full_name)) = SOUNDEX(NORMALIZE_FUNC('name surname'))

e eu obtenho uma varredura sequencial na tabela users.

Quando tento sem o definido pelo usuário NORMALIZE_FUNC:

CREATE INDEX users_full_name_soundex_idx ON users (SOUNDEX(full_name)) WHERE full_name IS NOT NULL;

SELECT *
FROM users
WHERE SOUNDEX(full_name) = SOUNDEX('name surname')

Vejo que o users_full_name_soundex_idxíndice é usado e a consulta é rápida.

O que estou perdendo?

postgresql
  • 1 respostas
  • 101 Views
Martin Hope
Hasan Can Saral
Asked: 2023-10-20 19:13:14 +0800 CST

Qual seria a desvantagem de uma verificação de exclusividade em um gatilho para uma tabela particionada?

  • 5

Eu tinha a seguinte tabela:

CREATE TABLE transactions
(
    id NUMERIC(20, 0) NOT NULL DEFAULT NEXTVAL('transactions_sequence') PARIMARY KEY,
    transaction_id VARCHAR(255) DEFAULT NULL NULL,
    transaction_amount NUMERIC(10,0) DEFAULT NULL NULL,
    customer_name VARCHAR(256) DEFAULT NULL NULL,
    transaction_date TIMESTAMP DEFAULT NULL NULL,
    CONSTRAINT uq_transactions_transaction_id UNIQUE (transaction_id)
);

CREATE INDEX transactions_transaction_id_idx ON transactions (transaction_id, id);

e quero particioná-lo da transaction_dateseguinte maneira:

CREATE TABLE transactions
(
    id NUMERIC(20, 0) NOT NULL DEFAULT NEXTVAL('transactions_sequence'),
    transaction_id VARCHAR(255) DEFAULT NULL NULL,
    transaction_amount NUMERIC(10,0) DEFAULT NULL NULL,
    customer_name VARCHAR(256) DEFAULT NULL NULL,
    transaction_date TIMESTAMP DEFAULT NULL NULL,
    CONSTRAINT transactions_pkey PRIMARY KEY (id, transaction_date),
    CONSTRAINT uq_transactions_transaction_id UNIQUE (transaction_id, transaction_date)
) PARTITION BY RANGE (transaction_date);

CREATE INDEX transactions_transaction_id_idx ON transactions (transaction_id, id);

com este particionamento transaction_idnão é verdadeiramente único, mas único por partição, pois a chave exclusiva deve ter a chave de partição, ou seja, transaction_date.

O aplicativo que usa esta tabela não reconhece o particionamento e usa o estado SQL 23505 para executar a atualização em vez de uma inserção.

Estou inserindo aproximadamente 300 mil linhas por dia e o tamanho atual da tabela é de aproximadamente 30 milhões de linhas.

O mesmo ocorre com o seguinte gatilho:

CREATE OR REPLACE FUNCTION transactions_validate() RETURNS TRIGGER
    LANGUAGE PLPGSQL
AS
$$
BEGIN
    IF EXISTS (SELECT id FROM transactions WHERE transaction_id = NEW.transaction_id AND id <> NEW.id) THEN
        RAISE EXCEPTION USING ERRCODE = '23505';
    END IF;
    RETURN NEW;
END;
$$;

CREATE TRIGGER transactions_validate_trigger
    BEFORE INSERT OR UPDATE
    ON transactions
    FOR EACH ROW
EXECUTE PROCEDURE transactions_validate();

Uma má ideia? Quais seriam as implicações de desempenho?

postgresql
  • 1 respostas
  • 48 Views
Martin Hope
Hasan Can Saral
Asked: 2023-09-05 02:33:53 +0800 CST

Quais bancos de dados implementam uma diferença entre varredura de índice e busca de índice?

  • 5

Digamos que eu tenha uma mesa:

CREATE TABLE transactions (
    id NUMERIC(20, 0) PRIMARY_KEY,
    account_id VARCHAR(512),
    ...
    transaction_date TIMESTAMP
);

Assim, com o SQL Server, um índice:

CREATE NONCLUSTERED INDEX my_index ON transactions (account_id, transaction_date, id);

e uma consulta:

SELECT id FROM transactions 
WHERE account_id = '123' 
AND transaction_date > '2023-01-01'

realiza uma busca de índice, ou seja, a consulta é atendida a partir do índice, não fazendo referência à tabela, pois todos os dados necessários estão presentes na tabela. Se meu índice fosse:

CREATE NONCLUSTERED INDEX my_index ON transactions (account_id, transaction_date);

a consulta iria para a tabela para atender a consulta (Index Scan). Qual dos seguintes bancos de dados:

  1. Oráculo
  2. MySQL
  3. PostgreSQL

apoiar o comportamento acima?

sql-server
  • 1 respostas
  • 64 Views
Martin Hope
Hasan Can Saral
Asked: 2023-06-06 17:04:16 +0800 CST

JOIN com uma tabela pequena faz com que o plano de execução mude e a consulta fique drasticamente lenta

  • 6

Eu tenho as seguintes tabelas:

CREATE TABLE acl_sid (
 id bigserial not null primary key,
 principal boolean not null,
 sid varchar(100) not null,
 constraint unique_uk_1 unique(sid,principal) );

CREATE TABLE users(
 id NUMERIC(20, 0) NOT NULL DEFAULT NEXTVAL('users_sequence') PRIMARY KEY,
 email VARCHAR(255) NOT NULL,
    -- some ~10 columns omitted
 );

CREATE TABLE authorities (
 user_id NUMERIC(20, 0) NOT NULL,
 sid_id  BIGINT         NOT NULL,
 CONSTRAINT fk_authorities_users FOREIGN KEY (user_id) REFERENCES users (id) ON UPDATE CASCADE ON DELETE CASCADE,
 CONSTRAINT fk_authorities_sids FOREIGN KEY (sid_id) REFERENCES acl_sid (id) ON UPDATE CASCADE ON DELETE CASCADE );


CREATE SEQUENCE decidables_sequence START WITH 1 NO MAXVALUE;


CREATE TABLE decidables (
 id NUMERIC(20, 0) NOT NULL DEFAULT NEXTVAL('decidables_sequence') PRIMARY KEY,
 assigned_to NUMERIC(20, 0) DEFAULT NULL NULL,
 CONSTRAINT fk_decidables_assigned_to FOREIGN KEY (assigned_to) REFERENCES users (id) ON UPDATE CASCADE ON DELETE SET NULL );

CREATE TABLE decidables_transactions (
 decidable_id NUMERIC(20, 0) NOT NULL PRIMARY KEY,
 transaction_date TIMESTAMP DEFAULT NULL NULL,
 transaction_id VARCHAR(255) DEFAULT NULL,
 -- some 100 columns here
 CONSTRAINT uq_decidables_transactions_transaction_id UNIQUE (transaction_id),
 CONSTRAINT fk_decidables_transactions_decidable_id FOREIGN KEY (decidable_id) REFERENCES decidables (id) ON UPDATE CASCADE ON DELETE CASCADE );

CREATE TABLE decidables_transactions_mv (
 decidable_id NUMERIC(20, 0) NOT NULL,
 transaction_date TIMESTAMP DEFAULT NULL NULL,
 -- some 10 columns here, excerpt from decidables_transactions
 assigned_to NUMERIC(20, 0) DEFAULT NULL NULL,
 CONSTRAINT fk_decidables_transactions_mv_decidable_id_idx FOREIGN KEY (decidable_id) REFERENCES decidables (id) ON UPDATE CASCADE ON DELETE CASCADE,
 CONSTRAINT fk_decidables_transactions_mv_assigned_to_idx FOREIGN KEY (assigned_to) REFERENCES users (id) ON UPDATE CASCADE ON DELETE SET NULL );

CREATE INDEX decidable_id_mv_idx ON decidables_transactions_mv (decidable_id);
-- few more indexes on omitted columns, that are not being used in the following queries
CREATE INDEX transaction_date_mv_idx ON decidables_transactions_mv (transaction_date, decidable_id);

Eu tenho esta consulta de paginação de conjunto de chaves que funciona muito bem:

SELECT d.*,
       t.*,
       u.id    AS ass_to_id,
       u.email AS ass_to_email,
       NULL    AS ass_to_authority
FROM decidables d
         JOIN decidables_transactions t ON d.id = t.decidable_id
         LEFT JOIN users u ON d.assigned_to = u.id AND u.deleted_at IS NULL
         -- some more joins omitted for simplicity
         JOIN (SELECT t.decidable_id, t.transaction_date
               FROM decidables_transactions_mv t
               ORDER BY t.transaction_date DESC, t.decidable_id DESC
               LIMIT 10) AS decidables_table ON d.id = decidables_table.decidable_id
ORDER BY t.transaction_date DESC, t.decidable_id DESC;

Mas quando tento selecionar a autoridade do usuário:

SELECT d.*,
       t.*,
       u.id  AS ass_to_id,
       u.email AS ass_to_email,
       s.sid AS ass_to_authority
FROM decidables d
         JOIN decidables_transactions t ON d.id = t.decidable_id
         LEFT JOIN users u ON d.assigned_to = u.id AND u.deleted_at IS NULL
         LEFT JOIN authorities a ON a.user_id = u.id
         LEFT JOIN acl_sid s ON a.sid_id = s.id
         -- some more joins omitted for simplicity
         JOIN (SELECT t.decidable_id, t.transaction_date
               FROM decidables_transactions_mv t
               ORDER BY t.transaction_date DESC, t.decidable_id DESC
               LIMIT 10) AS decidables_table ON d.id = decidables_table.decidable_id
ORDER BY t.transaction_date DESC, t.decidable_id DESC;

Começa a demorar alguns minutos. Eu tenho cerca de 10 linhas em ~ 10 userslinhas acl_side ~ 2 milhões em e decidables.decidables_transactionsdecidables_transactions_mv

Os planos de execução são os seguintes:

  • Consulta rápida
  • Consulta lenta

Por que a consulta tem um desempenho muito diferente e fica drasticamente lenta?

postgresql
  • 1 respostas
  • 39 Views
Martin Hope
Hasan Can Saral
Asked: 2023-01-31 02:41:15 +0800 CST

A tabela ORA-04091 está mutando, o gatilho/função pode não vê-lo quando em cascata, funciona de outra forma

  • 6

Tenho as duas tabelas a seguir:

CREATE TABLE entries
(
    id                  NUMBER(20, 0)                           NOT NULL PRIMARY KEY,        
    first_name          VARCHAR2(512) DEFAULT NULL              NULL,
    last_name           VARCHAR2(512) DEFAULT NULL              NULL,
    last_updated_at     TIMESTAMP     DEFAULT NULL              NULL
);

CREATE TABLE entry_details
(
    id       NUMBER(20, 0)              NOT NULL PRIMARY KEY,
    entry_id NUMBER(20, 0)              NOT NULL,
    value    VARCHAR2(512) DEFAULT NULL NULL,
    CONSTRAINT fk_details_entry_id FOREIGN KEY (entry_id) REFERENCES entries(id) ON DELETE CASCADE
);

Preciso atualizar last_updated_atsempre que houver uma alteração/exclusão na tabela entriesor entry_details, então tenho esta trigger:

CREATE OR REPLACE TRIGGER detail_delete_trigger
    BEFORE DELETE
    ON entry_details
    FOR EACH ROW
BEGIN
    UPDATE entries
    SET last_updated_at = CURRENT_TIMESTAMP
    WHERE id = :OLD.entry_id;
END;

Isso funciona bem quando há uma exclusão entry_detailsdiretamente. No entanto, recebo o ORA-04091: entries table is mutatingerro quando há exclusão da entriestabela que se propaga para entry_details. Eu tentei:

  1. PRAGMA AUTONOMOUS_TRANSACTIONSque cede aORA-00060: deadlock detected while waiting for resource
  2. Usando uma AFTER DELETEtrigger, que deu novamente, a tabela está com erro de mutação
  3. Não foi possível usar INSTEAD OF DELETEporque não é para tabelas conformeORA-25002: cannot create INSTEAD OF triggers on tables
  4. Eu removi CASCADEe adicionei o seguinte gatilho:

ALTER TABLE entry_details DROP CONSTRAINT fk_details_entry_id;
ALTER TABLE entry_detailsADD CONSTRAINT fk_details_entry_idFOREIGN KEY (entry_id) REFERENCES entries(id);

CREATE OR REPLACE TRIGGER aml_entries_delete_trigger
    BEFORE DELETE -- or AFTER DELETE, same result
    ON entries
    FOR EACH ROW
BEGIN
    DELETE FROM entry_details WHERE entry_id = :OLD.id;
END;

Mas ainda recebo o ORA-04091 table is mutating trigger/function may not seeerro. Como faço para superar isso?

oracle
  • 1 respostas
  • 35 Views
Martin Hope
Hasan Can Saral
Asked: 2022-09-10 23:50:55 +0800 CST

Avaliação paralela e mais rápida da contagem de comparação booleana SELECTing

  • 0

tenho uma tabela:

CREATE TABLE IF NOT EXISTS blacklist
(
    id                    NUMERIC(20, 0)                           NOT NULL DEFAULT NEXTVAL('blacklist_sequence') PRIMARY KEY,
    device_id             VARCHAR(512)   DEFAULT NULL              NULL,
    phone_number          VARCHAR(512)   DEFAULT NULL              NULL
);

CREATE INDEX index_phone ON blacklist (phone_number);
CREATE INDEX index_device ON blacklist (device_id);

e quero usar essa lista negra para ver se um cliente com device_idou a phone_numberestá dentro dela. Então minha consulta é:

SELECT CASE WHEN COUNT(*) > 0 THEN TRUE ELSE FALSE END
FROM blacklist b
         JOIN
     (SELECT id
      FROM blacklist 
      WHERE device_id = :deviceId
      UNION
      SELECT id
      FROM blacklist 
      WHERE phoneNumber = :phoneNumber) filtered_table ON b.id = filtered_table.id

Basicamente, dividindo a ORcondição em subconsultas UNIONpara fazer uso de índices, mas descobri que temos tantas linhas de lista negra com phone_numberlinhas preenchidas, enquanto menos com device_id.

Então, estou procurando uma maneira de paralelizar ainda mais para que quando uma device_idcorrespondência for encontrada, eu não precise ficar procurando coletar e UNIONos resultados da phone_numbercondição (porque nesse ponto eu já sei que o meu SELECTretornará TRUE) para venha com um maior COUNT, já que estou interessado apenas se a linha existe ou não.

Como faço para reescrever essa consulta para alcançá-la? Embora eu esteja procurando principalmente uma solução Postgres, estou interessado em descobrir o que outros bancos de dados podem fazer.

postgresql query-performance
  • 1 respostas
  • 46 Views
Martin Hope
Hasan Can Saral
Asked: 2021-09-03 20:42:40 +0800 CST

Como posso melhorar o desempenho da consulta com filtro na coluna datetime usando uma exibição indexada?

  • 2

Eu tenho essa tabela:

CREATE TABLE transactions
(
    id                                    NUMERIC(20, 0)              NOT NULL PRIMARY KEY,
    amount                                NUMERIC(18, 2) DEFAULT NULL NULL,
    -- Some 100 columns
    customer_msisdn                       VARCHAR(255)   DEFAULT NULL              NULL,
    customer_email                        VARCHAR(255)   DEFAULT NULL              NULL,
    payment_date                          DATETIME2                   NOT NULL
);

CREATE NONCLUSTERED INDEX msisdn_idx ON transactions (customer_msisdn, payment_date, id);
CREATE NONCLUSTERED INDEX email_idx ON transactions (customer_email, payment_date, id);

Estou indexando cerca de 1 milhão de linhas por mês. Com muita frequência, preciso selecionar as transações dos últimos 3 meses por customer_msisdnou por customer_email99% do tempo de 50 a 1.000 registros.

Aqui está minha consulta para um pouco mais de visão:

SELECT t.*
FROM transactions t
         JOIN (SELECT t.id
               FROM transactions t
                        WITH (FORCESEEK)
               WHERE t.customer_email = :customerEmail
                 AND t.payment_date >= :startDate
                 AND t.payment_date < :endDate
               UNION
               SELECT t.id
               FROM transactions t
                        WITH (FORCESEEK)
               WHERE t.customer_msisdn = :customerMsisdn
                 AND t.payment_date >= :startDate
                 AND t.payment_date < :endDate) AS filtered_transactions
              ON t.id= filtered_transactions.id
ORDER BY t.payment_date;

E eu sinto que desde que :endDateé sempre agora (e quando não, pode tolerar falhas) e :startDateé sempre três meses atrás, eu tenho algum espaço para melhorias. Aqui está o que eu pensei:

Crie uma exibição indexada com um filtro em payment_date:

CREATE VIEW [dbo].transactions_iv
    WITH SCHEMABINDING AS
SELECT [t].id,
       -- All the rows
       [t].customer_msisdn,
       [t].customer_phone,
       [t].payment_date
FROM [dbo].[transactions] [t]
WHERE [t].payment_date >= DATEADD(MONTH, -3, CURRENT_TIMESTAMP);

e meus índices:

CREATE NONCLUSTERED INDEX msisdn_iv_idx ON transactions_iv (customer_msisdn, id);
CREATE NONCLUSTERED INDEX phone_iv_idx ON transactions_iv (customer_phone, id);

e elimine as AND t.payment_date >= :startDate AND t.payment_date < :endDatecláusulas completamente da consulta. A consulta se torna:

SELECT t.*
FROM transactions_iv t
         JOIN (SELECT t.id
               FROM transactions_iv t
                        WITH (FORCESEEK)
               WHERE t.customer_email = :customerEmail
               UNION
               SELECT t.id
               FROM transactions_iv t
                        WITH (FORCESEEK)
               WHERE t.customer_msisdn = :customerMsisdn) AS filtered_transactions
              ON t.id= filtered_transactions.id
ORDER BY t.payment_date;

Como a exibição tem apenas as transações dos últimos 3 meses, estou assumindo que os índices também terão. Essa suposição está correta? O índice seria atualizado apenas para cobrir os registros dos últimos 3 meses e eu obteria meu aumento de desempenho?


Outra alternativa é:

  1. Crie outra tabela idêntica,
  2. Preenchê-lo com um gatilho na tabela principal
  3. Com um cron job, exclua registros com mais de 3 meses todas as noites.

Como essa opção se compara à anterior?

sql-server index
  • 1 respostas
  • 869 Views
Martin Hope
Hasan Can Saral
Asked: 2021-01-18 11:05:09 +0800 CST

Como adiciono índices compostos do MySQL com desnormalização e JOINS?

  • 1

Tenho as seguintes tabelas:

CREATE TABLE base_event (
    id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    created_by ... -- some columns
);

CREATE TABLE transaction_events (
    event_id BIGINT UNSIGNED NOT NULL,
    transaction_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    merchant_id BIGINT UNSIGNED NULL DEFAULT NULL,   
    merchant_city VARCHAR (...) NULL DEFAULT NULL, -- Denormalize
    customer_id BIGINT UNSIGNED NULL DEFAULT NULL,
    customer_ip_address VARCHAR(...) NULL DEFAULT NULL, -- Denormalize
    ...
    FOREIGN KEY (event_id) REFERENCES base_event(id),
    FOREIGN KEY (customer_id) REFERENCES customers(id),
    FOREIGN KEY (merchant_id) REFERENCES merchants(id),
);

CREATE TABLE customers (
    id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    customer_ip_address VARCHAR(...) NULL DEFAULT NULL,
    ...
);

CREATE TABLE merchants (
    id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    ...
);

E meu SELECT:

(SELECT t.*, c.name AS customer_name ...
FROM transaction_events t
JOIN customers c ON t.customer_id = c.id
JOIN merchants m ON t.merchant_id = m.id
WHERE t.customer_ip_address = 'abc' AND t.transaction_time > 'abc')
UNION DISTINCT
(SELECT t.*, c.name AS customer_name ...
FROM transaction_events t
JOIN customers c ON t.customer_id = c.id
JOIN merchants m ON t.merchant_id = m.id
WHERE t.merchant_city = 'abc' AND t.transaction_time > 'abc')

E meus índices são:

ALTER TABLE transaction_events 
ADD INDEX index_1 (customer_ip_address, transaction_time),
ADD INDEX index_2 (merchant_city, transaction_time);
  1. Minha consulta está neste formulário para evitar arquivos OR.
  2. Eu desnormalizei até certo ponto por causa dos índices.
  3. Não preciso referenciar minha base_eventtabela para esta consulta.
  4. A relação com transaction_eventsto customerse merchantsnão é 1-para-1, mas 1-para-0-ou-1.

Minhas perguntas:

  1. Eu posso me livrar do curinga, mas transaction_eventstem cerca de 20 colunas (ajudaria a criar mais índices para acelerar a consulta?
  2. Preciso colocar outros índices compostos (que potencialmente referenciam meus FKs) para melhorar ainda mais essa consulta?
mysql index
  • 2 respostas
  • 92 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