How can i Get Better Time Result on This Mysql Query - mysql

i am Using This Mysql Query and is working Good, But i need go get a Better Time result. How can i do it?
SELECT TblExistencias.id as ID, TblExistencias.codigo as Codigo,
TblPartes.detalle as Detalle,TblPartes.neto1 as PrecioActual,
TblExistencias.Condicion_Producto as Condicion,TblCategorias.categoria as Categoria,
TblSubcategorias.subcategoria as Subcategoria, TblExistencias.costo as Costo,
TblExistencias.serial as Serial, TblExistencias.vendido as Vendido,
TblConceptosFacturas.ventaonline as VentaOnline, TblRemitos.nroremitocompleto as Remito,
TblFacturas.nrofacturacompleto as Factura, TblFacturas.fecha as FechaVenta,
TblConceptosFacturas.ventaTotUn as Venta,TblConceptosFacturas.comisionmlunit as Comision,
TblFacturas.costoenvio as Envio, if(TblExistencias.vendido =1,
TblConceptosFacturas.ventaTotUn - TblExistencias.Costo - TblConceptosFacturas.comisionmlunit - TblFacturas.costoenvio,0) as Ganancia,
TblProveedores.razonsocial as Proveedor, TblFacturasCompras.nrofacturacompleto as Compra,
TblFacturasCompras.fecha as FechaCompra, TblClientes.razonsocial as Cliente
from TblExistencias
left join TblPartes on TblExistencias.codigo = TblPartes.codigo1
left join TblRemitos on TblExistencias.id_RemitoVenta = TblRemitos.id
left join TblFacturasCompras on TblExistencias.id_factura = TblFacturasCompras.id
left join TblClientes on TblRemitos.id_cliente = TblClientes.id
left join TblFacturas on TblRemitos.id_factura = TblFacturas.id
left join TblConceptosFacturas on TblFacturas.id=TblConceptosFacturas.id_factura and TblConceptosFacturas.codigoproducto = TblExistencias.codigo
left join TblCategorias on TblCategorias.id = TblPartes.id_categoria
left join TblSubcategorias on TblPartes.id_subcategoria = TblSubcategorias.id
left join TblProveedores on TblFacturasCompras.id_proveedor = TblProveedores.id
order by comision desc

The solution is create an index on each relational columns, like:
TblFacturasCompras.id_proveedor = TblProveedores.id

Problem was in order clause, Query passed from 87 Secs to 4 Secs. Thanks for help.

Related

MYSQL Merge two columns from two tables and still use LEFT JOIN

So I'm having a slight problem with having to save price on a product in two different tables due to a few reasons. Is it possible to merge two columns into one? I know UNION exists but does it work with LEFT JOIN's?
Any pointers is much appreciated.
Best Regards
SELECT
si.id AS shop_item_id,
si.item_price,
s.logo_file_name,
p.cat_id AS category_id,
api.item_price AS api_price,
MAX(c.campaign_desc) AS campaignDesc,
MAX(c.campaign_type_id) AS campaignType,
MAX(c.shop_id) AS campaign_shop_id,
MAX(ct.image_name) AS campaignLogo
FROM
shop_item si
LEFT JOIN
shop s ON
s.id = si.shop_id
LEFT JOIN
product p ON
si.product_id = p.id
LEFT JOIN
campaign_category cc ON
cc.category_id = p.cat_id
LEFT JOIN
campaign c ON
c.id = cc.campaign_id AND
c.shop_id = si.shop_id AND
c.show_in_pricetable = 1 AND
NOW() BETWEEN c.date_from and c.date_to
LEFT JOIN
campaign_type ct ON
c.campaign_type_id = ct.id
LEFT JOIN
shop_api_item api ON
si.rel_feed_api = api.unique_id AND si.shop_id = api.shop_id
WHERE
si.`product_id` = 586 AND
s.`active_shop` = 1
GROUP BY
s.name,
si.id ,
si.item_price
ORDER BY
si.`item_price`,
si.`shop_id`,
c.`campaign_desc` DESC
It looks like you would benefit from the COALESCE() function.
SELECT
si.id AS shop_item_id,
COALESCE(si.item_price, api.item_price) AS coalesced_price,
...
COALESCE() takes multiple arguments, and returns the first argument that is not NULL.

SQL Optimization - Query take 15 seconds

I have 400 rows every tables. So, I will try to relationship every tables using LEFT JOIN based on ID, but my query takes 15 seconds, and this is my query:
SELECT
sender.id AS id,
sender.letter AS letter,
sender.date AS date,
mediaseller.contract_number AS contract,
sender.company AS company,
brand.value AS brand,
sender.message_category AS message_category,
sender.message_format AS message_format,
sender.senderid AS senderid,
cpname.value AS cpname,
sid.value AS sid,
status.status AS status,
sender.remarks AS remarks,
user.name AS name,
sender.id AS download,
mediaseller.value AS mediaseller,
lob.value AS lob,
lob.subvalue AS sublob,
sms_type.value AS type_sms,
status.approval_date,
status.batch_date,
status.done_date,
status.decline_date
FROM status
LEFT JOIN sender ON status.trxid = sender.trxid
LEFT JOIN user ON status.userid = user.id
LEFT JOIN mediaseller ON sender.mediaseller = mediaseller.id
LEFT JOIN lob ON sender.industry_category = lob.id
LEFT JOIN sms_type ON sender.type_sms = sms_type.id
LEFT JOIN cpname ON sender.cpname = cpname.id
LEFT JOIN sid ON sender.trxid = sid.trxid
LEFT JOIN brand ON sender.brand = brand.id
WHERE status.hidden = 0
ORDER BY status.id DESC LIMIT 10
I hopeful is query takes one seconds :D
Please give me advice, Thankyou!
You are not filtering by anything other than the status. So try this:
FROM (SELECT s.*
FROM status s
WHERE s.hidden = 0
ORDER BY status.id DESC
LIMIT 10
) status
LEFT JOIN sender ON status.trxid = sender.trxid
LEFT JOIN user ON status.userid = user.id
LEFT JOIN mediaseller ON sender.mediaseller = mediaseller.id
LEFT JOIN lob ON sender.industry_category = lob.id
LEFT JOIN sms_type ON sender.type_sms = sms_type.id
LEFT JOIN cpname ON sender.cpname = cpname.id
LEFT JOIN sid ON sender.trxid = sid.trxid
LEFT JOIN brand ON sender.brand = brand.id
WHERE status.hidden = 0
ORDER BY status.id DESC LIMIT 10
You still need the outer ORDER BY and LIMIT, but they should be on much less data resulting in a performance improvement.
Note: I assume that you have declared all the ids as primary keys, so they have indexes.

mysql query very slow when adding subquery

I have below query , only 800 record taking 5 minits to run, can you some help please
SELECT
vtiger_salesorder.salesorderid,vtiger_salesorder.salesorder_no,vtiger_salesorder.sostatus,
(SELECT se.s_date
FROM
softMax_events as se
INNER JOIN vtiger_salesorder as bm ON bm.salesorderid = se.orderNum
where (bm.sostatus = 'Order' AND se.orderNum = vtiger_salesorder.salesorderid) AND se.appointTyp='60'
group by bm.salesorderid Limit 0,1) As sdate
FROM
vtiger_salesorder
Inner Join vtiger_crmentity ON vtiger_salesorder.salesorderid = vtiger_crmentity.crmid
WHERE (vtiger_salesorder.sostatus = 'Order')
and ( vtiger_crmentity.deleted<>'1')
Try this query, hope so this will help you,
SELECT vtiger_salesorder.salesorderid,vtiger_salesorder.salesorder_no,vtiger_salesorder.sostatus,se.s_date
FROM vtiger_salesorder
Inner Join vtiger_crmentity ON vtiger_salesorder.salesorderid = vtiger_crmentity.crmid
INNER JOIN softMax_events se ON se.orderNum = salesorderid
WHERE (vtiger_salesorder.sostatus = 'Order') AND/OR
se.orderNum = vtiger_salesorder.salesorderid AND se.appointTyp='60'
and ( vtiger_crmentity.deleted<>'1')
Edit:
I noticed that there is some relation between vtiger_salesorder and softMax_events and you can use a join for both table, and in this way you can remove that inner query, i tried it you may test it. this will help you for sure after a bit modification.

SQL query wrong result

i have this query:
SELECT `completed`.`ID` AS `ID`,`completed`.`level` AS `level`,`completed`.`completed_in` AS `completed_in`, COUNT(1) AS `right_answers_num`
FROM `completed`
INNER JOIN `history` ON `history`.`ID` = `completed`.`ID`
INNER JOIN `questions` ON `questions`.`ID` = `history`.`question`
WHERE `completed`.`student_id` = '1' AND `questions`.`answer` = `history`.`answer`
GROUP BY `completed`.`ID`
ORDER BY `completed`.`completed_in` DESC
what i need is to get info of each test in completed table (id,level,completed_in,right_answer_num)
the problem with that query is that if there is no one right answer(history.answer = questions.answer) then it doesn't return the row, while it should return the row(id,level,completed_in) and the right_answer_num(counter) should be zero..
please help me,, thanks ahead.
SELECT
completed.ID AS ID,
completed.level AS level,
completed.completed_in AS completed_in,
COUNT(questions.answer) AS right_answers_num
FROM completed
INNER JOIN history ON history.ID = completed.ID
LEFT JOIN questions ON questions.ID = history.question AND questions.answer = history.answer
WHERE
completed.student_id = '1'
GROUP BY
completed.ID
ORDER BY completed.completed_in DESC
use a LEFT OUTER JOIN intead of an INNER JOIN.
The second inner join is what's causing rows with no record in the questions table to be omitted. An inner join will only return rows that have data in all corresponding tables. Change the second inner join to a left join like so:
SELECT
completed.ID AS ID,
completed.level AS level,
completed.completed_in AS completed_in,
COUNT(questions.answer) AS right_answers_num
FROM completed
INNER JOIN history ON history.ID = completed.ID
LEFT JOIN questions ON questions.ID = history.question
WHERE completed.student_id = 1
GROUP BY completed.ID
ORDER BY completed.completed_in DESC

mysql join and count

Somehow am not successful with creating the query that I want.
DB is to do with locations, there are the following tables which are relevant
t_location - list of locations incl. field t_location_zipcode, and t_location_id_location
t_zipcodecity - join table just t_zipcodecity_zipcode t_zipcodecity_id_city
t_city - city list with t_city_id_city
t_citystate - join table, t_citystate_id_city, t_citystate_id_state
t_state - list of states with t_state_id_state
Initially I tried to get a list of states with locations using this query:
SELECT DISTINCT `t_state_id_state`
, `t_state_name_full`
FROM (`t_state`)
LEFT JOIN `t_citystate` ON `t_state_id_state` = `t_citystate_id_state`
LEFT JOIN `t_city` ON `t_citystate_id_state` = `t_city_id_city`
LEFT JOIN `t_zipcodecity` ON `t_city_id_city` = `t_zipcodecity_id_city`
LEFT JOIN `t_location` ON `t_zipcodecity_zipcode` = `t_location_zipcode`
ORDER BY `t_state_name_full` asc ­
which works fine.
Now what I also need / want which I am failing dismally at is to get the number of locations in each state. I don't know if it can be done in this one query or if i need another, either way I need help!
you can use a count and a group by. Something like this:
SELECT DISTINCT `t_state_id_state`
, `t_state_name_full`
, COUNT(*)
FROM (`t_state`)
LEFT JOIN `t_citystate` ON `t_state_id_state` = `t_citystate_id_state`
LEFT JOIN `t_city` ON `t_citystate_id_state` = `t_city_id_city`
LEFT JOIN `t_zipcodecity` ON `t_city_id_city` = `t_zipcodecity_id_city`
LEFT JOIN `t_location` ON `t_zipcodecity_zipcode` = `t_location_zipcode`
GROUP BY `t_state_id_state` , `t_state_name_full`
ORDER BY `t_state_name_full` asc
SELECT t_state_id_state
, t_state_name_full
, COUNT(DISTINCT t_location_id_location) AS locations_number
FROM
t_state
LEFT JOIN
t_citystate ON t_state_id_state = t_citystate_id_state
LEFT JOIN
t_city ON t_citystate_id_state = t_city_id_city
LEFT JOIN
t_zipcodecity ON t_city_id_city = t_zipcodecity_id_city
LEFT JOIN
t_location ON t_zipcodecity_zipcode = t_location_zipcode
GROUP BY t_state_id_state
ORDER BY t_state_name_full ASC ­
Ok thats looking good, my bad with the left joins, i was initially trying to get ALL the states which is why i used them. But i change that to use inner joins
SELECT t_state_id_state,
t_state_name_full,
COUNT(DISTINCT t_location_id_location) AS locations_number
FROM t_state
INNER JOIN t_citystate ON t_citystate_id_state = t_state_id_state
INNER JOIN t_city ON t_city_id_city = t_citystate_id_city
INNER JOIN t_zipcodecity ON t_zipcodecity_id_city = t_city_id_city
INNER JOIN t_location ON t_location_zipcode = t_zipcodecity_zipcode
GROUP BY t_state_id_state
ORDER BY t_state_name_full ASC
then i actually end up with a result that looks good !