0
I was having a problem of slowness in a select as below:
select
vendas.codigo, vendas.cartao_tipo, vendas.valor,
vendas.datavenda, venda.autorizacao,
cliente.codigo, cliente.nome, cliente.cpf,
cartao.numero_final, cartao.nome,
plano.nome, plano.max_parcela
from mv_vendas vendas
inner join mv_clientes clientes on(clientes.codigo = vendas.cli_codigo)
left join mv_cartoes cartao on(cartao.tipo = vendas.cartao_tipo)
left join mv_planos plano on(plano.codigo = vendas.plano_codigo)
where (vendas.datavenda between '2021-05-01' and '2021-05-31')
and(vendas.status = 'sucesso')
order by vendas.datavenda desc
limit 100,50
This SELECT in a table of 150 thousand records (with the appropriate index in the aggregated fields) takes 2,600s on my local machine, when I put it on the server takes 0.312s, a huge difference
Taking into account that my server is a Xeon 8 Cores and 16GB of Memory with SSD at first I ended up accepting the difference...
But then I started thinking, wait a minute... my laptop is an i5 with 8GB of memory and SSD, it can’t take that long... that’s when I started doing SQL tests to see if it improved the result on my machine, because 150,000 records on a table is next to nothing... I’ve worked with DBF with 10 million records and it was almost instantaneous...
I started to see that Mysql was reading the whole table to bring me the result of order by e limit, because when I took them it was much faster.
But as I need to paginate and bring ordered by descending date so I arrived at the following SELECT:
select
vendas.codigo, vendas.cartao_tipo, vendas.valor,
vendas.datavenda, venda.autorizacao,
cliente.codigo, cliente.nome, cliente.cpf,
cartao.numero_final, cartao.nome,
plano.nome, plano.max_parcela
from(
select * from mv_vendas
where (datavenda between '2021-05-01' and '2021-05-31')
and(status = 'sucesso')
order by datavenda desc
limit 100,50
) as vendas
inner join mv_clientes clientes on(clientes.codigo = vendas.cli_codigo)
left join mv_cartoes cartao on(cartao.tipo = vendas.cartao_tipo)
left join mv_planos plano on(plano.codigo = vendas.plano_codigo)
Analyzing, it makes sense because now I’m searching in the mv_sales table only what I really need and then I put together the aggregated tables data
Result: On my machine it makes the SELECT in 0.035s and on the server 0.032s
I am putting here on Stack to receive criticism from colleagues to know if I am on the right track because I am far from being a DBA, but I want to get the best that I can from the database when it comes to search time.
If you have suggestions so that I can improve this SELECT there, I am all ears.
Note. The tables mv_cards and mv_plans will not always have sales records so the use of left.
I’m not an expert on DB, but I think for someone to be able to answer you, you need to know 1) how the tables are; 2) how the query execution plan is; 3) which is the DBMS. By the way, the text got confused,?
– Rafael Tavares
The two return what I need, the problem is only the response time... and the SGDB is Mysql
– Marcelo
Clearly the response time is good, especially compared to the first query. I didn’t understand the doubt, it seems that you asked the question and the answer together.
– Rafael Tavares
I’d like to make sure I’m on the right track, because sometimes we think a select is fine by the response time, but the passage of time can show that this select would not bring the correct result from the base, leaving some record behind, so I posted.
– Marcelo