I have a query in my PHP where I'm searching for string:
select * from feed1 where PNAME like '%clothes%' limit 5;
I also want to get count of PNAME like cloth for which I'm using separate search query:
$qry=mysqli_query(select * from feed1 where PNAME like '%clothes%');
$rows=mysqli_num_rows($qry);
Rows query is taking too much time to load the page. Is there any way we can get total row count and limit of up to 5 products from one query? Thereby, the load time will decrease.
+-------+------------+----------+--------------+-------------+-----------+------
-------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardi
nality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+------
-------+----------+--------+------+------------+---------+---------------+
| xml | 0 | PRIMARY | 1 | BOSID | A |
7233 | NULL | NULL | | BTREE | | |
+-------+------------+----------+--------------+-------------+-----------+------
-------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
You can't do this by one query, but for get count, use COUNT(*) instead of get all the data out.
To get the count:
select count(*) from feed1 where PNAME like '%clothes%'
then get first 5:
select * from feed1 where PNAME like '%clothes%' limit 5
There should be at least two queries for pagination.
Related
I have a MySQL table that has three columns, the first is a unique key (INT(11) AUTO_INCREMENT), the next is an indexed value (VARCHAR(255)) and the third is a description (TEXT). There are duplicate values in the second column, but each row has a different description. I want to remove all rows where the second column is duplicated but append each description of the same indexed value to the first instance the value, and breaking string with a semicolon and space.
For example, my table looks like this:
cid | word | description
------------------------------
1 | cat | an animal with wiskers
2 | cat | a house pet
3 | dog | a member of the canine family
4 | cat | a cool person
I want to change the table to look like this:
cid | word | description
------------------------------
1 | cat | an animal with wiskers; a house pet; a cool person
3 | dog | a member of the canine family
I'm not adverse to using a PHP script to do this, but would prefer MySQL. The table has over 170,000 rows and would take PHP a long time to loop over it.
SQL:
select `cid`,`word`,group_concat(`description` SEPARATOR '; ') as `description` from `test_table` group by `word`;
Ok.. you can copy all the data into another table, and rename it then..
insert into `test_new` (`cid`,`word`,`desc`) (select `cid`,`word`,group_concat(`desc` SEPARATOR '; ') as `description` from `test_table` group by `word`);
mysql> describe `test_new`;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| word | char(10) | YES | | NULL | |
| desc | text | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> select * from `test_new`;
+------+------+---------------------+
| id | word | desc |
+------+------+---------------------+
| 1 | cat | desc1; desc2; desc4 |
| 3 | dog | desc3 |
+------+------+---------------------+
2 rows in set (0.00 sec)
As was mentioned before, you can create a new table and copy the info, you can also do it in two steps, but only if thereĀ“s no problem with modifying the old table:
UPDATE tableOld AS N1, tableOld AS N2
SET N1.description = concat(concat(N1.description,"; "),N2.decription))
WHERE N2.word = N1.word
insert into tableNew (cid,name,description)select * from tableOld group by word
Hello there, I have a schema like this, table name feeds
Where msg_id is unique and its the primary key of the table
| msg_id |commented|
| 1 | 10 |
| 2 | 10 |
| 3 | 10 |
| 4 | 21 |
I want to build a query that would select the last two rows
The output should go like this
| msg_id |commented|
| 3 | 10 |
| 4 | 21 |
In short the query should return the rows with msg_id which have a distinct commented value
Group by the column ment to be unique and select the highest id for every group
select max(msg_id) as msg_id, commented
from your_table
group by commented
Try this -
select max(msg_id), commented from your_table group by commented
SELECT * FROM feeds GROUP BY commented
how to get all the record from Mysql by supplying month in the query?
i am working in php project and i have a mysql table for posts in which all the posts are saved with their dates(not the publish date or post date but any random date).
now i am selecting the month from the front end and querying for the posts for the given month.
how to retrieve the posts that are in between that month ?
You could use MySQL's MONTH() function
SELECT * FROM tbl WHERE MONTH( date_col ) = 3
You can use MONTHName() function to check the data with the name of month you selected rom front-end.
SELECT * FROM tablename WHERE MONTHNAME(date_column) = "March"
you can fire this query
Select * from table where Date =>'$date1' and Date = '$date2'
to find data between any two dates
you can add where condition as
WHERE YEAR(col_name_of_date) = 2014 AND MONTH(Date) = 4";
or
WHERE YEAR(col_name_of_date) = YEAR(now()) AND MONTH(Date) = 4";
This will need the column col_name_of_date to be in DATE or DATETIME type.
Also you should avoid this kind of DATE() function since its a load to the mysql server.
Its better to construct the date parameter on PHP side before u pass them to query. If you
know the moth start and end and can easily construct the start and end date in Y-m-d format. For the start date d is always 01 and for the end date its the last day of the month.
Check how the query behaves using DATE() and without date
I have a table users where regdate is not indexed
explain select count(*) from users where year(regdate) = year(now()) and month(regdate) = 01 ;
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
| 1 | SIMPLE | users | ALL | NULL | NULL | NULL | NULL | 79309 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
As u can see num of rows it may scan is the upper limit of the table.
Now lets add an index
mysql> alter table users add index `u_regdate_idx`(`regdate`) ;
Query OK, 79309 rows affected (1.44 sec)
Records: 79309 Duplicates: 0 Warnings: 0
Now run the same again
mysql> explain select count(*) from users where year(regdate) = year(now()) and month(regdate) = 01 ;
+----+-------------+-------+-------+---------------+---------------+---------+------+-------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------------+---------+------+-------+--------------------------+
| 1 | SIMPLE | users | index | NULL | u_regdate_idx | 4 | NULL | 79309 | Using where; Using index |
+----+-------------+-------+-------+---------------+---------------+---------+------+-------+--------------------------+
As u can see there is no change in the performance.
Now lets change the query and see
mysql> explain select count(*) from users where regdate between '2014-01-01' AND '2014-01-31' ;
+----+-------------+-------+-------+---------------+---------------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------------+---------+------+------+--------------------------+
| 1 | SIMPLE | users | range | u_regdate_idx | u_regdate_idx | 4 | NULL | 1 | Using where; Using index |
+----+-------------+-------+-------+---------------+---------------+---------+------+------+--------------------------+
Now u can see its far better.
I have a table of 16K entries
I want to extract random 44 entries
but I don't want to repeat the same entries more then once (ever)
so i have a per-user list that keeps the already used 'IDs' as a comma-separated string in a table.
and I use that list to SELECT ... NOT IN (used_IDs)
The issue is that this list is getting too big and the sql call fails because of size i believe
Any idea on how to do that more usefully?
Questions table:
+------+-------+-------+
| id | Qtext | Tags |
+------+-------+-------+
Test table:
+------+-------+
| id | QIDs |
+------+-------+
Results table:
+------+-------+-------+
| id | tID | uID |
+------+-------+-------+
I need to select unique random values from Questions table based on the results table. (which associates test ID with Question IDs)
Currently trying to use:
SELECT DISTINCT `questions`.`ID`
FROM `questions`, `tests`, `results`
WHERE
`questions`.`ID` NOT IN (`tests`.`qIDs`)
AND `results`.`uID` = 1 AND `tests`.`ID` = `results`.`tID`
AND 4 IN ( `questions`.`tags`)
AND "http://www.usmlestep2qna.com" = `provider`
ORDER BY RAND() LIMIT 27;
Any ideas?
Instead of placing the used user Id values in a comma-separated string in one column, you could create a tall table to store them. This should yield better preformance
Rather than using a single row with a (potentially huge) CSV, why not use a nicely indexed table and an outer join to pick unmatched records. I have an example from my test database:
mysql> select * from first;
+------+-------+
| id | title |
+------+-------+
| 1 | aaaa |
| 2 | bbbb |
| 3 | cccc |
| 4 | NULL |
| 6 | gggg |
+------+-------+
5 rows in set (0.00 sec)
mysql> select * from second;
+------+----------+------+------+-------+------+
| id | first_id | one | two | three | four |
+------+----------+------+------+-------+------+
| 1 | 1 | 3 | 0 | 4 | 6 |
| 1 | 2 | 4 | 4 | 1 | 2 |
| 3 | 3 | 1 | NULL | 3 | 4 |
+------+----------+------+------+-------+------+
3 rows in set (0.00 sec)
mysql> select a.id from first a join second b on a.id=b.first_id;
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
+------+
3 rows in set (0.00 sec)
mysql> select a.id from first a
left outer join second b on a.id=b.first_id where b.first_id is null;
+------+
| id |
+------+
| 4 |
| 6 |
+------+
2 rows in set (0.00 sec)
This should improve your performance rather nicely.
is there any way to remove the MAX with something else, maybe the ASC LIMIT 1 to decrease database throttling? My query gets the maximum id and adds 1 to it.
This is my query:
$query = 'SELECT MAX(ID) +1 as maxidpost
FROM wp_posts';
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)) {
echo 'p='. $row['maxidpost'];
}
mysql_close();
What does the database tell you about your query? If id is indexed then
mysql> explain select max(id) + 1 from times;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
1 row in set (0.18 sec)
mysql> explain select id from times order by id ASC limit 1;
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | times | index | NULL | PRIMARY | 4 | NULL | 1 | Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
1 row in set (0.00 sec)
This is fine. adding limit 1 isn't going to give any noticeable performance improvements.
This shouldn't cause any kind of issues, are you having problems with this particular query?
The SQL MAX() function will automatically look for just one result. There's no need of LIMIT it in any way. If you want to improve that query try setting ID as index.
SELECT ID + as maxidpost FROM wp_posts ORDER BY ID DESC LIMIT 1;
or If the table have Auto_increment ID
SHOW TABLE STATUS LIKE 'wp_posts';
There should be a field called Auto_increment which should be exactly MAX(ID) + 1;