I'm making a search application, and I want to figure out how many results a certain query fetches in order to calculate how many pages of results there are. I basically have:
mysql_query("SELECT * FROM table WHERE conditions LIMIT $page*$items, $items");
Do I have to do a query w/o the limit clause to get the total number, or is there a better way? Thanks!
SELECT COUNT (*) FROM table WHERE conditions
SELECT COUNT(*)
FROM table
WHERE conditions
I see you're using PHP. Once you've run the query, why don't you mysql_num_rows in PHP? That way you won't need to run two queries.
$page_count=10 // no of rows per page
$record=mysql_query("select count(*) from table where conditions");
$row=mysql_fetch_row[0];
$no_of_pages = ceil($row/$page_count);
Related
Okay so I have a table which currently has 40000 rows and I need to SELECT them all. I use a index for id and url column and if I have to SELECT a value by id or url it's instant but if I have to SELECT * it's very slow. What I'm trying to do is searching my database and output the matches and I did this with a
while($arr = mysqli_fetch_array($query))
{ #code... echo $arr['whatever_i_need']."<br>"; }
$query = mysqli_query($link,"SELECT * FROM table");
In the future I will have hundreds of millions of rows in the database so I would like to return the search results fast in 1 sec or something. If you can give me solutions I would really appreciate! Thanks!
EDIT:
I don't want to display all of the data but I want to loop through it quickly to find all the matches
If you want speed then you definitely don't want the query to return every row from the table, and then "loop through" every row returned by the query to identify the ones you are interested in returning. That approach might give acceptable performance with small tables, but it definitely doesn't scale.
For performance, you want the database to locate just the rows you want to return, filter out the ones you don't want, and return just the subset.
And that comes down to writing an appropriate SQL query; executing an appropriate SELECT statement.
SELECT t.col1
, t.col2
, t.col3
FROM mytable t
WHERE t.col3 LIKE '%foo%'
AND t.col2 >= '2016-03-15'
AND t.col2 < '2016-06-15'
ORDER BY t.col2 DESC, t.col1 DESC
LIMIT 200
Performance is about making sure appropriate indexes are available and that the query execution is making effective use of the available indexes.
I need to filter (using where clauses) the rows in my table, count the total number of rows from this filter and then limit number of rows for pagination.
What is quickest/more efficient?
Count the rows with sql query. Select the rows with a limit with sql query.
Select all rows with sql query. Count the array with PHP. Split the array with PHP.
Or is there another way to count all rows and get a limited set of the results out?
You should use SQL_CALC_FOUND_ROWS and the FOUND_ROWS() function to return the total number of rows even when a LIMIT is applied to the returned results. After you run your query the results will be returned, and then you can run SELECT FOUND_ROWS() to return the total number of rows without having to run the query again.
SELECT SQL_CALC_FOUND_ROWS * FROM my_table WHERE column = 'something' LIMIT 10;
SELECT FOUND_ROWS() AS total_results;
Use two queries, one to retrieve total number of rows, another to get the rows. The first argument in LIMIT clause specifies the offset of the first row ( current_page * post_per_page ), and the second specifies the maximum number of rows to return ( post_per_page ).
SELECT COUNT(*) AS num_rows FROM table;
SELECT * FROM table LIMIT start, length;
The MySQL LIMIT should do the trick for you. This is a more efficient approach, as it helps in fetching only the relevant records to be displayed and nothing else.
Note that the startingIndex, numberOfRecordsPerPage variables should be set before executing the query.
SELECT * FROM MY_TABLE where
(...) //ALL CONDITIONS go here
LIMIT startingIndex, numberOfRecordsPerPage;
From the MySQL Reference
With two arguments, the first argument specifies the offset of the
first row to return, and the second specifies the maximum number of
rows to return. The offset of the initial row is 0 (not 1):
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
In order to identify whether or not to expect any records in return, one must first run the query (with COUNT and without any LIMIT condition):
`SELECT COUNT(*) FROM MY_TABLE where (...) //ALL CONDITIONS go here`
and store it separately. This shall be the total records applicable to the WHERE clauses given.
If the sum startingIndex+numberOfRecordsPerPage is >= TOTAL_COUNT then that paginated set shall be the last of the whole list and the user should not be allowed to click the NEXT button.
PS: Also, as pointed out in the comments, you might want to look at a framework alternative, like Criteria API for Java, to the heavy weightlifting, particularly if your WHERE conditions are also generated dynamically.
Please help me figure out how to put the following two statements into one query. Your help is much appreciated.
$sql1 = 'SELECT COUNT(id) as total_cat_votes FROM votes WHERE category_id="1"';
$sql2 = 'SELECT COUNT(nominee_id') as total_nom_votes FROM votes WHERE category_id="1" AND nominee_id="16"';
My Idea here is I have a table called votes and I want to get the number of total votes for a specific category under category_id as well as the different total votes of each nominee under nominee_id. I hope I am clear enough.
Thanks for the help!
Use SUM() for the second count with a condition, using sum with a condition will result in a boolean as 0 or 1,also using aggregate functions without grouping them will result in a single row
SELECT COUNT(id) as total_cat_votes,
SUM(nominee_id='16') as total_nom_votes
FROM votes
WHERE category_id='1'
I would like to know if it is possible to retrive one single random row from search results. I mean I have query like this:
SELECT mp.name,mp.icon,mp.id,mp.wspx,mp.wspy,ms.icon FROM maps_points as mp JOIN maps_section as ms ON(ms.id = mp.section)
I would like to get one random row from results generated from this query. Is that possible with one mysql query or should I just get all results and get this one random in PHP?
a simple way is to add ORDER BY RAND() LIMIT 1 to the query. Do take a look at some of the reasons why this can be a bad idea though, e.g.
Why don't use mysql ORDER BY RAND()?
MySQL: Alternatives to ORDER BY RAND()
How can i optimize MySQL's ORDER BY RAND() function?
SELECT mp.name,mp.icon,mp.id,mp.wspx,mp.wspy,ms.icon
FROM maps_points as mp
JOIN maps_section as ms ON(ms.id = mp.section)
ORDER BY RAND() LIMIT 1
Ok, I knew this one, but is there better and faster way to do that ? I mean I've seen some other approaches but they were all about random row from table and I need to pick random row from some set of results :)
To randomly select records from one table; do I have to always set a temporary variable in PHP? I need some help with selecting random rows within a CodeIgniter model, and then display three different ones in a view every time my homepage is viewed. Does anyone have any thoughts on how to solve this issue? Thanks in advance!
If you don't have a ton of rows, you can simply:
SELECT * FROM myTable ORDER BY RAND() LIMIT 3;
If you have many rows, this will get slow, but for smaller data sets it will work fine.
As Steve Michel mentions in his answer, this method can get very ugly for large tables. His suggestion is a good place to jump off from. If you know the approximate maximum integer PK on the table, you can do something like generating a random number between one and your max PK value, then grab random rows one at a time like:
$q="SELECT * FROM table WHERE id >= {$myRandomValue}";
$row = $db->fetchOne($q); //or whatever CI's interface to grab a single is like
Of course, if you need 3 random rows, you'll have three queries here, but as they're entirely on the PK, they'll be fast(er than randomizing the whole table).
I would do something like:
SELECT * FROM table ORDER BY RAND() LIMIT 1;
This will put the data in a random order and then return only the first row from that random order.
I have this piece of code in production to get a random quote. Using MySQL's RAND function was super slow. Even with 100 quotes in the database, I was noticing a lag time on the website. With this, there was no lag at all.
$result = mysql_query('SELECT COUNT(*) FROM quotes');
$count = mysql_fetch_row($result);
$id = rand(1, $count[0]);
$result = mysql_query("SELECT author, quote FROM quotes WHERE id=$id");
you need a query like this:
SELECT *
FROM tablename
WHERE somefield='something'
ORDER BY RAND() LIMIT 3
It is taken from the second result of
http://www.google.com/search?q=mysql+random
and it should work ;)
Ordering a big table by rand() can be very expensive if the table is very large. MySQL will need to build a temporary table and sort it. If you have primary key and you know how many rows are in the table, use LIMIT x,1 to grab a random row, where x is the number of the row you want to get.