I have a page called profile.php I need information from multiple tables from within the same database.
Are multiple queries the way to deal with this, like this:
//connect
//query1
//query2
//query3
//query4
Mysqli_Query(connect, query1)
Mysqli_Query(connect, query2)
Mysqli_Query(connect, query3)
Mysqli_Query(connect, query4)
There is certainly nothing stopping you from making multiple queries, but depending on what you're doing, a JOIN is likely far more appropriate.
There's more to cover here than can reasonably fit in a StackOverflow answer, so please try a tutorial: http://www.tizag.com/mysqlTutorial/mysqljoins.php
Unless you're gathering data from query1 and using it in query2 and so on, you can optimize multiple queries into a single query by using UNION or JOIN. That's all I can offer without seeing any actual code.
what i get from your question is that there are many tables and you just need information from them, in that case it is better to go for UNION or JOIN over multiple queries as long as the tables are somehow related.
Related
I'm having an inner debate at my company about looping queries in this matter:
$sql = "
SELECT foreign_key
FROM t1";
foreach(fetchAll($sql) as $row)
{
$sub_sql = "
SELECT *
FROM t2
WHERE t2.id = " . $row['foreign_key'];
foreach(fetchAll($sub_sql) as $sub_row)
{
// ...
}
}
Instead of using an sql join like this:
$sql = "
SELECT t2.*
FROM t2
JOIN t1
ON t1.foreign_key = t2.id";
foreach(fetchAll($sql) as $row)
{
// ...
}
Additional information about this, the database is huge, millions of rows.
I have of course searched an answer to this question, but nobody can answer this in a a good way and with a lot of up votes that makes me certain that one way is better then the other.
Question
Can somebody explain to me why one of thees methods is better then the other one?
The join method is generally considered better, if only because it reduces the overhead of sending queries back and forth to the database.
If you have appropriate indexes on the tables, then the underlying performance of the two methods will be similar. That is, both methods will use appropriate indexes to fetch the results.
From a database perspective, the join method is far superior. It consolidates the data logic in one place, making the code more transparent. It also allows the database to make optimizations that might not be apparent in application code.
Because of driver overhead, a loop is far less efficient
This is similar to another question I answered, but different enough not to cv. My full answer is here but I'll summarize the main points:
Whenever you make a connection to a database, there are three steps taken:
A connection to the database is established.
A query, or multiple queries, to the database is executed.
Data is returned for processing.
Using a loop structure, you will end up generating additional overhead with driver requests, where you will have a request and a return per loop cycle rather than a single request and single return. Even if the looped queries do not take any longer than the single large query (this is very unlikely as MySQL internals have a lot of shortcuts built in to prevent using a full repetitive loop), you will still find that the single query is faster on driver overhead.
Using a loop without TRANSACTIONS, you will also find that you run into relational data integrity issues where other operations affect the data you're iterating between loop cycles. Using transactions, again, increases overhead because the database has to maintain two persistent states.
I have PHP script to add new record and check this record in table1,table2 and table3 if record not exist than add it into table3 else update the record to table1 or table2 (where its exist).
I have large data to check. So its possible to perform this task using single MySQL query.
Thanks in advance.
Please keep in mind, that joining two large tables may be a lot slower than using 2 or 3 separate query to get data out of them one by one. The main question is what you consider huge. Joining millions of rows is never a good idea in MySQL AFAIK if you have large rows.
So while having it done in one query is definitely possible it may not be the economical thing to do.
We also need some info about row sizes, indexes, basic query syntax and stuff like that.
I'm trying to get results back if two cases match:
table_users.Email='user#email.com'
table_devices.DeviceUuid='51ec969c-8546-41f4-a748-ec2458c81d17'
But, I get empty results even though table_users.Email='user#email.com' exists!!!
SELECT table_users.Email, table_users.DeleteFlag, table_devices.DeviceUuid
FROM table_users, table_devices
WHERE table_users.Email='user#email.com'
OR table_devices.DeviceUuid='51ec969c-8546-41f4-a748-ec2458c81d17';
What am I missing...? I'd rather not break this into two queries for performance reasons.
Thanks!
Do your php code assume that just one record is returned, while in fact many may be returned?
If the two tables are not related in any way, you should use two queries to obtain the information you want. Without a join condition, your query will be far less efficient than using two separate queries, as you will get one record for each row not matched by your query.
If you insist on using just one query, try this:
SELECT Email, DeleteFlag, NULL AS DeviceUuid
FROM users
WHERE Email='user#email.com'
UNION
SELECT NULL AS Email, NULL AS DeleteFlag, DeviceUuid
FROM devices
WHERE DeviceUuid = '51ec969c-8546-41f4-a748-ec2458c81d17';
Your original query should also work if you change OR into AND, and if the given Device Uuid is found in the table.
Turns out, the only way to do this is definitely in two separate queries, because I'm checking to see if two things exist in two separate tables and there no way to join them, since one of them may not exist.
For the logic I need, two separate SELECT queries is the only solution apparently.
Thanks for the help anyways guys!
Maybe it's a little dumb, but i'm just not sure what is better.
If i have to check more than 10k rows in db for existanse, what i'd do?
#1 - one query
select id from table1 where name in (smth1,smth2...{till 30k})
#2 - many queries
select id from table1 where name=smth1
Though, perfomance is not the goal, i don't want to go down with mysql either ;)
Maybe, any other solutions will be more suitable...
Thanks.
upd: The task is to fetch domains list, save new (that are not in db yet) and delete those that dissappeared from list. Hope, it'll help a little...
What you should do is create a temp table, insert all of the names, and (using one query) join against this table for your select.
select id
from table1 t1
inner join temptable tt on t1.name = tt.name
The single query will most likely perform better as the second will give a lot of round-trip delays. But if you have a lot of names like in your example the first method might cause you to hit an internal limit.
In this case it might be better to store the list of names in a temporary table and join with it.
Depending on your future needs to do similar things, you might want to add a function in the database 'strlist_to_table'. Let the function take a text where your input is delimited by a delimiter character (possibly also passed to function), split it on the delimiter to create a on-the-fly table. Then you can use
where in strlist_to_table('smth1|smth2', '|')
and also get protection from sql injection (maybe little Bobby Tables appears in the input).
Just my 2 cents...
I'm not sure how flexible your application design is, but it might be worth looking into removing the delimited list altogether and simply making a permanent third table to represent the many-to-many relationship, then joining the tables on each query.
I have a classifieds website.
I am using SOLR for indexing and storing data. Then I also have a MySQL db with some more information about the classified which I dont store or index.
Now, I have a pretty normalized db with 4 tables.
Whenever ads are searched on the website, SOLR does the searching and returns an array of ID_numbers which will then be used to query mysql.
So solr returns id:s, which are then used to get all ads from the mysql db with THOSE id:s.
Now, all the JOIN and relations between my tables gives me a headache.
What except for maintanance-ease do I get for having a normalized db?
I could you know, store all info into one table with some 50 columns.
So instead of this for finding one ad and displaying it:
SELECT
category_option.option_name,
option_values.value
FROM classified, category_option, option_values
WHERE classified.classified_id=?id
AND classified.cat_id=category_options.cat_id
AND option_values.option_id=category_options.option_id
I could use this:
SELECT * FROM table_name WHERE classified_id = $classified_id
Isn't the last one actually faster?
Or does a normalized db permform faster?
Thanks
I would advise against denormalizing in your situation. You'll get better with joins as you use them more and they start to become clearer in your head, and maintenance ease is a good benefit for the future.
Here's a pretty good link about normalization (and denormalization). Here's a question about denormalization. One answer suggests creating a view using joins to get the data you need, and using that like your SELECT * FROM table_name WHERE classified_id = $classified_id query. A normalized DB will likely be slower, but it's unlikely you'll want to denormalize for that reason. I hope this provides some help.
Whenever you do denormalization you usually gain reading speed and lose write speed, because you have to write the same value many times. Additionally, extra care should be taken to maintain data integrity.
How many times the query will be executed?
Is this a high traffic application?
Can you add a cache?
The query using a JOIN is trivial as far as MySQL joins are concerned. I see no need to denormalize this.
I would however suggest rewriting it to not be such a PITA to read:
SELECT
category_option.option_name,
option_values.value
FROM classified
JOIN category_option USING (cat_id)
JOIN option_values USING (option_id)
WHERE classified.classified_id = ?