Inner join works Too Slower - just show loading label in phpmyadmin - mysql

I have 3 tables each have almost 70,000 data
when i execute select query in which i add one inner join than it works faster.
Following works faster
select A.id from product as A
inner join product_cat as B on A.id=B.mapped_id
OR
select A.id from product as A
inner join product_sup as C on A.id = C.mapped_id
(It works faster for one inner join)
but when i add both inner join in same select query than it works too slower(Does not display data it just show loading label in phpmyadmin)
select A.id
from product as A
inner join product_cat as B
on A.id = B.mapped_id
inner join product_sup as C
on A.id = C.mapped_id
my purpose it only to find out how much record is there in database.
also tried with count function though takes too much time.
Any help will be appreciated,
Thanks,

Use EXPLAIN to analyze performance of the query and identify any missing indexes.
http://dev.mysql.com/doc/refman/5.5/en/using-explain.html
http://dev.mysql.com/doc/refman/5.5/en/explain-output.html
Add your actual query, execution plan printed by EXPLAIN and CREATE TABLE statements of all involved tables to your question if you want to get a specific advice.

Maybe your query is trying to return more than 1 million of result and that is the reason fo the slowness. Maybe you are doing a Cartesian product between tables B and C.
Let's put an example.
Table (A) = (id=1)
Table (B) = (id=1,mapped_id=1),(id=2,mapped_id=1),
(id=3,mapped_id=1),(id=4,mapped_id=1)
Table (C) = (id=1,mapped_id=1),(id=2,mapped_id=1), (id=3,mapped_id=1)
If we do that query with those data it would return 12 rows, all of them with A.id=1
To solve the problem you could try to use a DISTINCT on the SELECT clause or to do a group with the GROUP BYclase, but I think the better solution is to redesing the query depending on your goals.
If you want to use the group by your query will be something like this
select A.id from product as A
inner join product_cat as B on A.id = B.mapped_id
inner join product_sup as C on A.id = C.mapped_id
group by A.id

Related

SQL inner join multiple tables with one query

I've a query like below,
SELECT
c.testID,
FROM a
INNER JOIN b ON a.id=b.ID
INNER JOIN c ON b.r_ID=c.id
WHERE c.test IS NOT NULL;
Can this query be optimized further?, I want inner join between three tables to happen only if it meets the where clause.
Where clause works as filter on the data what appears after all JOINs,
whereas if you use same restriction to JOIN clause itself then it will be optimized in sense of avoiding filter after join. That is, join on filtered data instead.
SELECT c.testID,
FROM a
INNER JOIN b ON a.id = b.ID
INNER JOIN c ON b.r_ID = c.id AND c.test IS NOT NULL;
Moreover, you must create an index for the column test in table c to speed up the query.
Also, learn EXPLAIN command to the queries for best results.
Try the following:
SELECT
c.testID
FROM c
INNER JOIN b ON c.test IS NOT NULL AND b.r_ID=c.testID
INNER JOIN a ON a.id=b.r_ID;
I changed the order of the joins and conditions so that the first statement to be evaluated is c.test IS NOT NULL
Disclaimer: You should use the explain command in order to see the execution.
I'm pretty sure that even the minor change I just did might have no difference due to the MySql optimizer that work on all queries.
See the MySQL Documentation: Optimizing Queries with EXPLAIN
Three queries Compared
Have a look at the following fiddle:
https://www.db-fiddle.com/f/fXsT8oMzJ1H31FwMHrxR3u/0
I ran three different queries and in the end, MySQL optimized and ran them the same way.
Three Queries:
EXPLAIN SELECT
c.testID
FROM c
INNER JOIN b ON c.test IS NOT NULL AND b.r_ID=c.testID
INNER JOIN a ON a.id=b.r_ID;
EXPLAIN SELECT c.testID
FROM a
INNER JOIN b ON a.id = b.r_id
INNER JOIN c ON b.r_ID = c.testID AND c.test IS NOT NULL;
EXPLAIN SELECT
c.testID
FROM a
INNER JOIN b ON a.id=b.r_ID
INNER JOIN c ON b.r_ID=c.testID
WHERE c.test IS NOT NULL;
All tables should have a PRIMARY KEY. Assuming that id is the PRIMARY KEY for the tables that it is in, then you need these secondary keys for maximal performance:
c: INDEX(test, test_id, id) -- `test` must be first
b: INDEX(r_ID)
Both of those are useful and "covering".
Another thing to note: b and a is virtually unused in the query, so you may as well write the query this way:
SELECT c.testID,
FROM c
WHERE c.test IS NOT NULL;
At that point, all you need is INDEX(test, testID).
I suspect you "simplified" your query by leaving out some uses of a and b. Well, I simplified it from there, just as the Optimizer should have done. (However, elimination of tables is an optimization that it does not do; it figures that is something the user would have done.)
On the other hand, b and a are not totally useless. The JOIN verify that there are corresponding rows, possibly many such rows, in those tables. Again, I think you had some other purpose.

join nested queries in from clause

Can you tell me what I need to manipulate in this query to get it working?
select C.ID from
(select A.ID from CUSTOMERS A inner join PROFILES B on A.ID=B.ID where CTR='67564' and CST_CD in
('G','H')) as C
inner join
(select ID from RELATION_CODES where R_CD='KC') as R
on C.ID=R.ID
The individual inner queries are working just fine and giving correct results, not sure what is the problem with inner join in from clause..
Not completely sure I'm understanding your question, but this should be able to be rewritten without the subqueries:
select c.id
from customers c
join profiles p on c.id = p.id
join relation_codes rc on rc.id = c.id
where ctr = '67564'
and cst_cd in ('G','H')
and rc.r_cd = 'KC'
If this isn't working, please provide your table structure and sample data and expected results. This should get you pretty close though.
I have to ask, is the id field in the relation_codes table and the profiles table the same as the id in the customers table. Perhaps you need to identify how your tables are related.
A Visual Explanation of SQL Joins

SQL statement that hangs DB

I was trying to cross reference 2 tables using the following query from myPhpAdmin app:
select A.*
from purchases A
where A.user in (
select B.user
from users B
where B.ppi = 'Facebook Ads'
)
It accepted the syntax but the DB never returned. The users table is not small, 200k rows, but i run querys on it all the time so it shouldn't take that long.. Any ideas as to why this might not work? The query was stuck in the state:Sending data. I had to kill it because my database was broken at this point so I cannot run any other checks on this now and Im scared to try again :)
Running on mysql FYI.
What I really wanted was just to be able to operate on values in table purchases only when the same user id is present in the other table with the given ppi value.
Use a join and make sure, you have indices on B.user and B.ppi.
SELECT A.*
FROM purchases A
INNER JOIN users B ON A.user=B.user
WHERE B.ppi = 'Facebook Ads'
A join should be faster than a subquery. Try this:
Select A.* from purchases A
INNER JOIN users B on A.user = B.user
WHERE B.ppi='Facebook Ads'

Select Query in MySQL for multiple tables

I m working in MySQL and have to write a select query.
I have related data in four tables. Now, the parent table may have data whose child data may not be present in lower tables.
I want to write a single query to get data from all four tables, irrespective of situation that data is present in child tables or not.
I have tried to write nested select and joins as below, but m not getting the data.
select * from property p where p.Re_ID in
(select Re_id from entry e where e.Re_ID in
(select Re_id from category c where c.Re_ID in
(select id from re)))
Please help me how to get data from all 4 tables.
If cir_registry is the master, you can select from that and LEFT JOIN the other tables in the order they're distant from cir_registry;
SELECT r.ID rId, r.Description rDescription, c.ID cId ...
...
p.Data_Type pDataType
FROM cir_registry r
LEFT JOIN cir_category c ON c.Registry_ID = r.ID
LEFT JOIN cir_entry e ON e.Category_ID = c.ID
LEFT JOIN cir_property p ON p.Entry_IDInSource = e.IDInSource
You should also alias the columns as above, otherwise, for example, p.ID and c.ID will both show up in the result set as ID, and you'll only be able to access one of them.
You might need UNION? Something like:
Select * FROM cir_registry
Union
Select * FROM cir_entry
Union
Select * FROM cir_property
Check the official doc here: http://dev.mysql.com/doc/refman/5.0/en/union.html

Search data from two table with joins how to handler null values

I have write a search query that will joining two different table. i have putted left join on both. Now first table contains 60records while based on that second table has only 30. Now i wanted if i search query should return all 60records. right now it is returning 30.
query same.
select A.,B. from A left join B on A.Id=B.AId where
A.name=IfNull('tst',A.name) AND B.class=IFNull('c',B.class).
Please guide me, Thanks.
It's wise to remember that JOIN operations (all kinds of JOIN operations, LEFT, RIGHT, INNER, OUTER) have the purpose of creating a new, virtual, table that is assembled from the tables joined together.
What is this JOINed virtual table supposed to have in it? In your case, what is the meaning of your column A.ID, and your column B.AID?
Are there rows in your A table with A.ID column values which occur no times in B.AID?
Are there rows in your B table with B.AID column values which occur no times in A.ID?
If the answer to question 1 is Yes and question 2 is No, then a LEFT JOIN will give you want you want. But simplify your query. Try this.
SELECT A.*, B.*
FROM A
LEFT JOIN B ON A.ID = B.AID
If you happen to want only the rows from A where there is no corresponding row from B, try this.
SELECT A.*
FROM A
LEFT JOIN B ON A.ID = B.AID
WHERE B.AID IS NULL
If the answer to both questions is Yes, then you may want this:
SELECT A.*, B.*
FROM A
OUTER JOIN B ON A.ID = B.AID
But you should think this through very carefully.
Try this Logic i hope it will work for you.....
select A.*,B.* from A left join B on A.Id=B.AId where B.Id != ''