Slow: Getting the results count of a query using a subquery - mysql

All I'd like to know is how many records there are in my query results but MySQL keeps kicking me off saying I have lost my connection. The query itself runs in about a second.
SELECT COUNT(*) FROM
(SELECT my208.eid AS contact, name AS the_status, cid208.lastmod AS status_date, boo208.boo_medium
FROM the_emails.my208
LEFT JOIN the_emails.cid208 ON cid208.eid = my208.eid
LEFT JOIN the_emails.boo208 ON boo208.eid = my208.eid
LEFT JOIN the_config.classes ON boo208.class_id = classes.id) foo
Why is this taking so long and is there a better way?

Include the count(*) in your inner query itself. See the modified query below.
Give it a try
SELECT my208.eid AS contact,
name AS the_status,
cid208.lastmod AS status_date,
boo208.boo_medium,
COUNT(*) as total_records
FROM the_emails.my208
LEFT JOIN the_emails.cid208 ON cid208.eid = my208.eid
LEFT JOIN the_emails.boo208 ON boo208.eid = my208.eid
LEFT JOIN the_config.classes ON boo208.class_id = classes.id

Related

SQL query optimization for speed

So I was working on the problem of optimizing the following query I have already optimized this to the fullest from my side can this be further optimized?
select distinct name ad_type
from dim_ad_type x where exists ( select 1
from sum_adserver_dimensions sum
left join dim_ad_tag_map on dim_ad_tag_map.id=sum.ad_tag_map_id and dim_ad_tag_map.client_id=sum.client_id
left join dim_site on dim_site.id = dim_ad_tag_map.site_id
left join dim_geo on dim_geo.id = sum.geo_id
left join dim_region on dim_region.id=dim_geo.region_id
left join dim_device_category on dim_device_category.id=sum.device_category_id
left join dim_ad_unit on dim_ad_unit.id=dim_ad_tag_map.ad_unit_id
left join dim_monetization_channel on dim_monetization_channel.id=dim_ad_tag_map.monetization_channel_id
left join dim_os on dim_os.id = sum.os_id
left join dim_ad_type on dim_ad_type.id = dim_ad_tag_map.ad_type_id
left join dim_integration_type on dim_integration_type.id = dim_ad_tag_map.integration_type_id
where sum.client_id = 50
and dim_ad_type.id=x.id
)
order by 1
Your query although joined ok, is an overall bloat. You are using the dim_ad_type table on the outside, just to make sure it exists on the inside as well. You have all those left-joins that have NO bearing on the final outcome, why are they even there. I would simplify by reversing the logic. By tracing your INNER query for the same dim_ad_type table, I find the following is the direct line. sum -> dim_ad_tag_map -> dim_ad_type. Just run that.
select distinct
dat.name Ad_Type
from
sum_adserver_dimensions sum
join dim_ad_tag_map tm
on sum.ad_tag_map_id = tm.id
and sum.client_id = tm.client_id
join dim_ad_type dat
on tm.ad_type_id = dat.id
where
sum.client_id = 50
order by
1
Your query was running ALL dim_ad_types, then finding all the sums just to find those that matched. Run it direct starting with the one client, then direct with JOINs.

Not getting the right results using GROUP_CONCAT in query

I have 7 tables to work with inside a query:
tb_post, tb_spots, users, td_sports, tb_spot_types, tb_users_sports, tb_post_media
This is the query I am using:
SELECT po.id_post AS id_post,
po.description_post as description_post,
sp.id_spot as id_spot,
po.date_post as date_post,
u.id AS userid,
u.user_type As tipousuario,
u.username AS username,
spo.id_sport AS sportid,
spo.sport_icon as sporticon,
st.logo_spot_type as spottypelogo,
sp.city_spot AS city_spot,
sp.country_spot AS country_spot,
sp.latitud_spot as latitudspot,
sp.longitud_spot as longitudspot,
sp.short_name AS spotshortname,
sp.verified_spot AS spotverificado,
u.profile_image AS profile_image,
sp.verified_spot_by as spotverificadopor,
uv.id AS spotverificador,
uv.user_type AS spotverificadornivel,
pm.media_type AS mediatype,
pm.media_file AS mediafile,
GROUP_CONCAT(tus.user_sport_sport) sportsdelusuario,
GROUP_CONCAT(logosp.sport_icon) sportsdelusuariologos,
GROUP_CONCAT(pm.media_file) mediapost,
GROUP_CONCAT(pm.media_type) mediaposttype
FROM tb_posts po
LEFT JOIN tb_spots sp ON po.spot_post = sp.id_spot
LEFT JOIN users u ON po.uploaded_by_post = u.id
LEFT JOIN tb_sports spo ON sp.sport_spot = spo.id_sport
LEFT JOIN tb_spot_types st ON sp.type_spot = st.id_spot_type
LEFT JOIN users uv ON sp.verified_spot_by = uv.id
LEFT JOIN tb_users_sports tus ON tus.user_sport_user = u.id
LEFT JOIN tb_sports logosp ON logosp.id_sport = tus.user_sport_sport
LEFT JOIN tb_post_media pm ON pm.media_post = po.id_post
WHERE po.status = 1
GROUP BY po.id_post,uv.id
I am having problems with some of the GROUP_CONCAT groups:
GROUP_CONCAT(tus.user_sport_sport) sportsdelusuario is giving me the right items but repeated, all items twice
GROUP_CONCAT(logosp.sport_icon) sportsdelusuariologos is giving me the right items but repeated, all items twice
GROUP_CONCAT(pm.media_file) mediapost is giving me the right items but repeated four times
GROUP_CONCAT(pm.media_type) mediaposttype s giving me the right items but repeated four times
I can put here all tables structures if you need them.
Multiple one-to-many relations JOINed in a query have a multiplicative affect on aggregation results; the standard solution is subqueries:
You can change
GROUP_CONCAT(pm.media_type) mediaposttype
...
LEFT JOIN tb_post_media pm ON pm.media_post = po.id_post
to
pm.mediaposttype
...
LEFT JOIN (
SELECT media_post, GROUP_CONCAT(media_type) AS mediaposttype
FROM tb_post_media
GROUP BY media_post
) AS pm ON pm.media_post = po.id_post
If tb_post_media is very big, and the po.status = 1 condition in the outer query would significantly reduce the results of the subquery, it can be worth replicating the original join within the subquery to filter down it's results.
Similarly, the correlated version I mentioned in the comments can also be more performant if the outer query has relatively few results. (Calculating the GROUP_CONCAT() for each individually can cost less than calculating it for all once if you would only actually using very few of the results of the latter).
or just add DISTINCT to all the group_concat, e.g., GROUP_CONCAT(DISTINCT pm.media_type)

How to Optimize my JOIN's to speed up my Query?

I have 6 queries like the following query listed below..
each are taking 6 seconds to run
for a total of 36 seconds for page to load
Is there a way to optimize these kinds of queries?
SELECT
tickets.ticketID,
tickets.ticket,
tickets.name1,
tickets.address1,
tickets.city,
tickets.cstate,
tickets.zip,
tickets.caller_type,
tickets.phone,
tickets.caller,
tickets.caller_phone,
tickets.contact,
tickets.contact_phone,
tickets.call_back,
tickets.location,
tickets.printable_text,
tblnotes.ntDate,
tblnotes.ntText,
tblstatus.stDesc,
tblUsers.username
FROM tblusers
RIGHT OUTER JOIN tickets ON tblusers.ID = tickets.ownerID
LEFT OUTER JOIN tblstatus ON tblstatus.stID = tickets.statusID
LEFT OUTER JOIN tblnotes ON tblnotes.ntID = tickets.noteID
WHERE tblstatus.stDesc <> "Closed"
EDIT: try this
SELECT
tickets.ticketID,
tickets.ticket,
tickets.name1,
tickets.address1,
tickets.city,
tickets.cstate,
tickets.zip,
tickets.caller_type,
tickets.phone,
tickets.caller,
tickets.caller_phone,
tickets.contact,
tickets.contact_phone,
tickets.call_back,
tickets.location,
tickets.printable_text,
tblnotes.ntDate,
tblnotes.ntText,
tblstatus.stDesc,
tblUsers.username
FROM tickets
INNER JOIN tblusers ON tblusers.ID = tickets.ownerID
INNER JOIN tblstatus ON tblstatus.stID = tickets.statusID
LEFT OUTER JOIN tblnotes ON tblnotes.ntID = tickets.noteID
WHERE tickets.statusID <> 3
posting as an answer, as I am unable to comment
You have a condition where tblstatus.stDesc <> "Closed"
assuming you have an index here on stID
change that to where tblstatus.stID <> put the id value
also change your left outer joins to inner joins, as any ways you have a where condition, you can keep the left join on tblnotes as I am not sure if it may have a row corresponding to tbltickets
i will also move the tickets table to from and then do an inner join with tblusers
use left outer join only when the join table may not have data, but you still want to show data from your main table

sql query doesn't return enough rows

I having trouble figuring out this SQL Query (MySql 5 is the server).
My tables are related like this:
My Query looks like this:
select
tblCustomer.customerNo,
tblSalesHeader.invoiceNo,
tblSalesHeader.orderDate,
tblSalesDetail.quantity,
tblSalesDetail.productNo,
tblSalesDetail.description,
tblSalesDetail.unitPrice
FROM
tblSalesHeader
left JOIN tblSalesDetail ON (tblSalesHeader.invoiceNo = tblSalesDetail.invoiceNo)
left JOIN tblCustomer ON (tblSalesHeader.cID = tblCustomer.cid)
left JOIN tblUsers ON (tblSalesHeader.salesmanID = tblUsers.iID)
left JOIN tblProducts ON (tblSalesDetail.productNo = tblProducts.productNumber)
WHERE
tblSalesHeader.invoiceNo=2482
GROUP BY
tblCustomer.customerNo,
tblSalesHeader.invoiceNo,
tblSalesDetail.productNo
I know that there should be 5 rows returned because there are 5 rows in tblSalesDetail where the invoiceNo=2482 like so:
select *
from
tblSalesDetail
left join tblSalesHeader on (tblSalesHeader.invoiceNo = tblSalesDetail.invoiceNo)
where
tblSalesHeader.invoiceNo=2482
I'm sure that my joins are filtering results out but I don't know why.
Get rid of the GROUP BY. You're not using it.

Query with joins

I am running a query:
select course.course,iars.id,
students.rollno,
students.name as name,
teachers.name as tname,
students.studentid,
attndata.studentid ,sum(attndata.obt) as obt
sum(attndata.benefits) as ben , (sum(attndata.max)) as abc
from groups, students
left join iars
on iars.id
left join str
on str.studentid=students.studentid
left join course
on course.c_id=students.course
left join teachers
on teachers.id=iars.teacherid
join sgm
on sgm.studentid=students.studentid
left join attndata
on attndata.studentid=students.studentid and iars.id=attndata.iarsid
left join sps
on sps.studentid=students.studentid and iars.paperid=sps.paperid
left join semdef
on semdef.semesterid=str.semesterid
where students.course='1'
and students.status='regular'
and sps.paperid='5'
and iars.courseid=students.course
and iars.semester=str.semesterid
and semdef.month=9
and iars.paperid='5'
and str.semesterid='1'
and str.sessionid='12'
and groups.id=sgm.groupid
group by sps.studentid,
teachers.id,
semdef.month
order by
students.name
In this query whenever I am having left join on semdef.id=attndata.mon, I am getting zero result when the value of semdef.id=null but I want all the results, irrespective of semdef, but I want to use it. As in it should fetch result, if the values are null. Can you please help it out.
It's probably because your where clause is saying
and semdef.month=9
and you probably want
and (semdef.month=9 OR semdef.id IS NULL)
or something similar.
It's because your where clause has statements relating to the semdef table. Add these to the join clause as putting these in the where is implying an inner join.
Eg:
Left join semdef on xxx and semdef.id = attndata.min