How do I speed up this 1.7 Second Mysql Query? - mysql

I'm writing a webapp in PHP where a list of users can be voted on. The query I'm using to pull a user from the table is quite slow. I suspect there is a much more efficient way to check if the target user has already been voted on by the active user.
SELECT *
FROM users
WHERE id NOT IN (
SELECT ratedid
FROM votes
WHERE who LIKE 12707264
)
AND picture1 NOT LIKE ''
AND cp1 < '10'
AND gender NOT LIKE 'male'
ORDER BY RAND( )
LIMIT 1
Table data as follows:
>SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
>SET time_zone = "+00:00";
/*!40101 SET #OLD_CHARACTER_SET_CLIENT=##CHARACTER_SET_CLIENT */;
/*!40101 SET #OLD_CHARACTER_SET_RESULTS=##CHARACTER_SET_RESULTS */;
/*!40101 SET #OLD_COLLATION_CONNECTION=##COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
--
-- Database: `notchus_userdb`
--
-- --------------------------------------------------------
--
-- Table structure for table `users`
--
CREATE TABLE IF NOT EXISTS `users` (
`id` bigint(20) NOT NULL,
`username` varchar(30) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`first_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`last_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`bio` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`picture1` varchar(200) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`cp1` int(100) DEFAULT NULL,
`picture2` varchar(200) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`picture3` varchar(200) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`friends` blob,
`relationship_status` varchar(20) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`relationship_interest` varchar(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`verified` int(1) NOT NULL,
`gender` varchar(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`birthday` varchar(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`hometown` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`citylocation` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`oauth_provider` varchar(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`oauth_uid` int(11) NOT NULL,
`ratchet` int(1) DEFAULT NULL,
`boss` int(1) DEFAULT NULL,
`isadmin` int(1) DEFAULT NULL,
`views` int(10) NOT NULL,
`reviews` int(10) NOT NULL,
`email` varchar(50) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`isuser` int(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `username` (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Server version: 5.1.70-cll
-- PHP Version: 5.3.17
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET #OLD_CHARACTER_SET_CLIENT=##CHARACTER_SET_CLIENT */;
/*!40101 SET #OLD_CHARACTER_SET_RESULTS=##CHARACTER_SET_RESULTS */;
/*!40101 SET #OLD_COLLATION_CONNECTION=##COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
--
-- Database: `notchus_userdb`
--
-- --------------------------------------------------------
--
-- Table structure for table `votes`
--
CREATE TABLE IF NOT EXISTS `votes` (
`uqid` int(11) NOT NULL AUTO_INCREMENT,
`value` tinyint(4) NOT NULL,
`picture` int(11) DEFAULT NULL,
`ratedid` bigint(20) DEFAULT NULL,
`comment` int(11) DEFAULT NULL,
`quote` int(11) DEFAULT NULL,
`who` bigint(20) NOT NULL,
`votedate` int(11) NOT NULL,
`control` varchar(100) NOT NULL,
PRIMARY KEY (`uqid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1084 ;

First of all, LIKE is only for doing wildcard matching. I'm surprised that you're not getting an error doing a LIKE on an integer. Then again, nothing MySQL does surprises me.
SELECT *
FROM users
WHERE id NOT IN (
SELECT ratedid
FROM votes
WHERE who = 12707264
)
AND picture1 <> ''
AND cp1 < '10'
AND gender <> 'male'
ORDER BY RAND( )
LIMIT 1
Also note that if it's OK for picture1 to be an empty string, then you shouldn't have a NOT NULL on the column, and you should store a NULL in the column where is no picture.

Your like statements don't appear to be using wildcards, I see no reason to use them here. Try changing them to equal signs. Indexing your tables could help you as well.

You don't appear to have indices on the foreign key relationships.
try:
create index who on votes (who);
create index q1 on users (picture1, cp1, gender);
Also, you appear to be confused about "like" and "=" - when comparing an integer column (e.g. CP1), use cp1 < 1 or who = 12707264.

Related

How to migrate MYSQL database with having different column name?

I have two database old.sql & new.sql.
I have user table named user in new.sql. and users in old.sql.
table structure for user from new.sql
--
-- Table structure for table `user`
--
DROP TABLE IF EXISTS `user`;
/*!40101 SET #saved_cs_client = ##character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT,
`email` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`password` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`firstName` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`lastName` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`phoneNumber` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL,
`role` enum('USER','ADMIN') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'USER',
`createdOn` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
PRIMARY KEY (`id`),
UNIQUE KEY `User_email_key` (`email`),
UNIQUE KEY `User_phoneNumber_key` (`phoneNumber`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = #saved_cs_client */;
and users from old.sql
DROP TABLE IF EXISTS `users`;
/*!40101 SET #saved_cs_client = ##character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `users` (
`id` int NOT NULL AUTO_INCREMENT,
`roleId` int NOT NULL,
`firstName` varchar(255) DEFAULT NULL,
`lastName` varchar(255) DEFAULT NULL,
`email` varchar(255) NOT NULL,
`password` varchar(255) DEFAULT NULL,
`status` tinyint(1) DEFAULT '1',
`resetPasswordExpires` datetime DEFAULT NULL,
`resetPasswordToken` varchar(255) DEFAULT NULL,
`createdAt` datetime NOT NULL,
`updatedAt` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
KEY `roleId` (`roleId`),
CONSTRAINT `Users_ibfk_1` FOREIGN KEY (`roleId`) REFERENCES `roles` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=884 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = #saved_cs_client */;
now I want to migrate user from old database to new database.
this is only one table, we have many tables to migrate data.
how can I achieve that ?
also we have done normalization in new database like
old.sql one table separated in 2 or 3 new tables in new database.
These DBs are on the same MySQL instance.
You can use a simple script like:
INSERT INTO
user (id, email, password, firstName, lastName, phoneNumber, role, createdOn)
SELECT
id, email, password, firstName, lastName, null, IF(roleId = 1, 'ADMIN', 'USER'), created
FROM users;
Just set correct roleId for condition and remove id if you need a new one.
Tiny example of the data transferring realization with some remarks: DEMO fiddle

Sql constraint error references other column

I don't know a lot of mysql and have an error in my sql script. Currently running mysql 8.0.24. Does anyone know what might be the problem?
Error:
https://prnt.sc/226xk5x
Sql:
-- Dumping structure for table gtav_rp2._vehicle
CREATE TABLE IF NOT EXISTS `_vehicle` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`cid` int(11) unsigned NOT NULL,
`vin` varchar(50) NOT NULL DEFAULT '',
`type` varchar(50) NOT NULL DEFAULT '',
`size` int(11) NOT NULL,
`plate` varchar(50) NOT NULL DEFAULT '',
`model` varchar(50) NOT NULL DEFAULT '',
`name` varchar(50) DEFAULT NULL,
`garage` varchar(59) DEFAULT NULL,
`state` varchar(50) DEFAULT NULL,
`appearance` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid('appearance')),
`mods` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid('mods')),
`data` longtext DEFAULT NULL,
`damage` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid('damage')),
`degredation` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid('degredation')),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- Dumping data for table gtav_rp2._vehicle: ~0 rows (approximately)
/*!40000 ALTER TABLE `_vehicle` DISABLE KEYS */;
/*!40000 ALTER TABLE `_vehicle` ENABLE KEYS */;
/*!40101 SET SQL_MODE=IFNULL(#OLD_SQL_MODE, '') */;
/*!40014 SET FOREIGN_KEY_CHECKS=IF(#OLD_FOREIGN_KEY_CHECKS IS NULL, 1, #OLD_FOREIGN_KEY_CHECKS) */;
/*!40101 SET CHARACTER
_SET_CLIENT=#OLD_CHARACTER_SET_CLIENT */;
Your CHECK constraint does not reference the column. Or any column, actually. By using single-quotes, you're using a string literal, not a column name.
`appearance` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL
CHECK (json_valid('appearance')),
I assume this is meant to be:
`appearance` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL
CHECK (json_valid(`appearance`)),
Use the right type of quotes for SQL identifiers, not string literals.
In addition, this CHECK constraint would be unnecessary if you used the JSON data type instead of LONGTEXT. The JSON data type already enforces that the content of the column must be valid JSON format.
MySQL's JSON data type already uses utf8mb4 character set and utf8mb4_bin collation.
So your column definition could be simply as follows:
`appearance` JSON

Importing sql file from phpmyadmin create error

I have successfully backup sql database. But whenever trying to import it shows some error. Like below:
MySQL said: Documentation
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'STORED,
`purchase_gst` decimal(10,2) NOT NULL,
`purchase_due` decimal(10,2' at line 8
Here is my code extracted from SQL file:
DROP TABLE IF EXISTS `purchase`;
/*!40101 SET #saved_cs_client = ##character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `purchase` (
`purchase_id` bigint(20) NOT NULL AUTO_INCREMENT,
`purchase_date` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`purchase_item` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`purchase_rate` decimal(10,2) DEFAULT NULL,
`purchase_qty` decimal(10,2) NOT NULL,
`purchase_from` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`purchase_gross` decimal(10,2) GENERATED ALWAYS AS ((`purchase_qty` * `purchase_rate`)) STORED,
`purchase_gst` decimal(10,2) NOT NULL,
`purchase_due` decimal(10,2) NOT NULL,
`purchase_tcost` decimal(10,2) NOT NULL,
`purchase_net` decimal(10,0) GENERATED ALWAYS AS (round(((`purchase_gross` + `purchase_gst`) + `purchase_tcost`),0)) STORED,
PRIMARY KEY (`purchase_id`)
) ENGINE=InnoDB AUTO_INCREMENT=372 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = #saved_cs_client */;
Please check the version of MySQl .This will work on MySQl 5.7 and above versions.
It's depends on your mySql version.
This sql syntax error shows below the MySQL 5.7 version.
Please Check this with in MySQL 5.7 version it's working with below code:
DROP TABLE IF EXISTS `purchase`;
/*!40101 SET #saved_cs_client = ##character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `purchase` (
`purchase_id` bigint(20) NOT NULL AUTO_INCREMENT,
`purchase_date` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`purchase_item` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`purchase_rate` decimal(10,2) DEFAULT NULL,
`purchase_qty` decimal(10,2) NOT NULL,
`purchase_from` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`purchase_gross` decimal(10,2) GENERATED ALWAYS AS (`purchase_qty` * `purchase_rate`) STORED,
`purchase_gst` decimal(10,2) NOT NULL,
`purchase_due` decimal(10,2) NOT NULL,
`purchase_tcost` decimal(10,2) NOT NULL,
`purchase_net` decimal(10,0) GENERATED ALWAYS AS (round(((`purchase_gross` +
`purchase_gst`) + `purchase_tcost`),0)) STORED,
PRIMARY KEY (`purchase_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;`enter code here`

I am missing a closing bracket was expected. (near ")" at position 136)

I received this error while uploading SQL to server phpMyAdmin. I did look at the answers from similar posts, but I don't think it's the same thing. It should be after -- Table structure for table wzflh_admintools_log. These are lines 127 through 146:
CREATE TABLE `wzflh_admintools_ipblock` (
`id` bigint(20) UNSIGNED NOT NULL,
`ip` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`description` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `wzflh_admintools_log`
--
CREATE TABLE `wzflh_admintools_log` (
`id` bigint(20) UNSIGNED NOT NULL,
`logdate` datetime NOT NULL,
`ip` varchar(40) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`reason` enum('other','adminpw','ipwl','ipbl','sqlishield','antispam','wafblacklist','tpone','tmpl','template','muashield','csrfshield','badbehaviour','geoblocking','rfishield','dfishield','uploadshield','xssshield','httpbl','loginfailure','securitycode','external','awayschedule','admindir','sessionshield','nonewadmins','nonewfrontendadmins','configmonitor','phpshield') COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`extradata` longtext COLLATE utf8mb4_unicode_ci
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
I have created a database named mydb and imported your tables via the console. This is what I have:
-- phpMyAdmin SQL Dump
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
CREATE TABLE `wzflh_admintools_ipblock` (
`id` bigint(20) UNSIGNED NOT NULL,
`ip` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`description` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `wzflh_admintools_log` (
`id` bigint(20) UNSIGNED NOT NULL,
`logdate` datetime NOT NULL,
`ip` varchar(40) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`reason` enum('other', 'adminpw', 'ipwl', 'ipbl', 'sqlishield',
'antispam', 'wafblacklist', 'tpone', 'tmpl',
'template', 'muashield', 'csrfshield',
'badbehaviour', 'geoblocking', 'rfishield',
'dfishield', 'uploadshield', 'xssshield', 'httpbl',
'loginfailure', 'securitycode', 'external',
'awayschedule', 'admindir', 'sessionshield',
'nonewadmins', 'nonewfrontendadmins', 'configmonitor',
'phpshield') COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`extradata` longtext COLLATE utf8mb4_unicode_ci
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Copy and paste this to your SQL file:
-- phpMyAdmin SQL Dump
-- version 4.5.1
-- http://www.phpmyadmin.net
--
-- Host: 127.0.0.1
-- Generation Time: Oct 19, 2017 at 07:46 PM
-- Server version: 10.1.16-MariaDB
-- PHP Version: 5.6.24
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET #OLD_CHARACTER_SET_CLIENT=##CHARACTER_SET_CLIENT */;
/*!40101 SET #OLD_CHARACTER_SET_RESULTS=##CHARACTER_SET_RESULTS */;
/*!40101 SET #OLD_COLLATION_CONNECTION=##COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `centeroakland`
--
-- --------------------------------------------------------
--
-- Table structure for table `wzflh_admintools_ipblock`
--
CREATE TABLE `wzflh_admintools_ipblock` (
`id` bigint(20) UNSIGNED NOT NULL,
`ip` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`description` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- --------------------------------------------------------
--
-- Table structure for table `wzflh_admintools_log`
--
CREATE TABLE `wzflh_admintools_log` (
`id` bigint(20) UNSIGNED NOT NULL,
`logdate` datetime NOT NULL,
`ip` varchar(40) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`reason` enum('other','adminpw','ipwl','ipbl','sqlishield','antispam','wafblacklist','tpone','tmpl','template','muashield','csrfshield','badbehaviour','geoblocking','rfishield','dfishield','uploadshield','xssshield','httpbl','loginfailure','securitycode','external','awayschedule','admindir','sessionshield','nonewadmins','nonewfrontendadmins','configmonitor','phpshield') COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`extradata` longtext COLLATE utf8mb4_unicode_ci
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET CHARACTER_SET_CLIENT=#OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=#OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=#OLD_COLLATION_CONNECTION */;
Save it then import it.

Getting Inconsistent Sorting Results from MySQL Query on LIMIT changes

My query (both below) return inconsistent sorting results as I increment pages (ex. LIMIT 3,3 to LIMIT 4,3). See the example image below and notice I have two new items despite only changing the FROM index by 1.
Worst of all, I cannot produce any particular sorting order consistently, except for the first set: LIMIT 0, 6. Then LIMIT 6,6 and other variations return wildly different results. For example, if i change the WANT value, i can get a completely different set of items.
Example:
http://trackauthoritymusic.com/wwwroot/images/pagination-error-proof.jpg
Environment:
echo mysql_get_server_info(); // 5.1.67-log
echo PHP_VERSION; // 5.4.14
character_set_client == utf8
character_set_connection == utf8
character_set_database == utf8
character_set_filesystem == binary
character_set_results == utf8
character_set_server == latin1
character_set_system == utf8
collation_connection == utf8_unicode_ci
collation_database == utf8_unicode_ci
collation_server == latin1_swedish_ci
I am using codeigniter but i'm using standard sql seen below.
On a shared hosting package
Queries:
SELECT S.*, G.* FROM games C LEFT JOIN songs T ON G.game_id = S.game_id WHERE G.game_status != 'deleted' and G.game_status != 'hidden' AND G.group_id = 1 GROUP BY G.game_id ORDER BY ISNULL(G.game_uploading_starts), G.game_listening_starts desc LIMIT 4, 3
SELECT S.*, G.* FROM games C LEFT JOIN songs T ON G.game_id = S.game_id WHERE G.game_status != 'deleted' and G.game_status != 'hidden' AND G.group_id = 1 GROUP BY G.game_id ORDER BY (CASE WHEN G.game_uploading_starts IS NULL then 1 ELSE 0 END), G.game_listening_starts desc LIMIT 4, 3
Both of these queries produce inconsistent sorting results, not simple different sets between the two of them.
Queried Table Schema:
DROP TABLE IF EXISTS `games`;
/*!40101 SET #saved_cs_client = ##character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `games` (
`game_id` mediumint(6) NOT NULL AUTO_INCREMENT,
`group_id` mediumint(6) NOT NULL,
`game_status` enum('playlist','game','compilation','halloffame','theme','deleted','hidden') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'hidden' COMMENT 'except deleted, this is not maintained at runtime, but on a cron job',
`game_title` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`game_image` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`game_author_id` mediumint(6) NOT NULL,
`game_ta_id` mediumint(6) DEFAULT NULL,
`game_winner_id` mediumint(6) DEFAULT NULL,
`song_id` mediumint(6) DEFAULT NULL COMMENT 'either first example or 1st place song if awarded already',
`game_buyin` int(11) DEFAULT NULL,
`game_minpool` int(11) DEFAULT NULL,
`game_rating_avg` tinyint(3) DEFAULT NULL,
`game_songs_per_user` tinyint(2) NOT NULL DEFAULT '1',
`game_uploading_starts` int(10) DEFAULT NULL,
`game_listening_starts` int(10) DEFAULT NULL,
`game_rating_starts` int(10) DEFAULT NULL,
`game_awarding_starts` int(10) DEFAULT NULL,
`game_uploading_ends` int(10) DEFAULT NULL,
`game_awarding_complete` int(10) DEFAULT NULL,
`game_created` int(10) NOT NULL,
`game_summary` varchar(2000) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`game_id`),
KEY `game_status` (`game_status`,`song_id`)
) ENGINE=MyISAM AUTO_INCREMENT=37 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = #saved_cs_client */;
DROP TABLE IF EXISTS `songs`;
/*!40101 SET #saved_cs_client = ##character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `songs` (
`song_id` mediumint(6) NOT NULL AUTO_INCREMENT,
`game_id` mediumint(6) NOT NULL,
`group_id` tinyint(3) NOT NULL,
`user_id` mediumint(6) NOT NULL,
`user_vendor_id` tinyint(1) DEFAULT NULL,
`receipt_id` mediumint(6) DEFAULT NULL,
`song_status` enum('example','game','playlist','compilation','deleted','winner') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'example',
`song_title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`song_artist` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`song_album` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`song_released` smallint(4) DEFAULT NULL,
`song_genre` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`song_location` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`song_reason` varchar(2500) COLLATE utf8_unicode_ci DEFAULT NULL,
`song_image` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`song_rating_avg` smallint(3) NOT NULL DEFAULT '0',
`song_adjusted_avg` decimal(5,2) NOT NULL DEFAULT '0.00',
`song_rated_count` mediumint(6) NOT NULL DEFAULT '0',
`win_rating` smallint(3) DEFAULT NULL,
`song_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`song_added` int(11) NOT NULL,
`song_order` int(4) DEFAULT NULL,
`song_dedication` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`song_id`),
KEY `game_id` (`game_id`),
KEY `user_id` (`user_id`),
KEY `song_status` (`song_status`)
) ENGINE=MyISAM AUTO_INCREMENT=305 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
/*!40101 SET character_set_client = #saved_cs_client */;
I assume the problem is that you have multiple rows that have the same value for G.game_listening_starts. These rows can be returned in any order, from one sort to the next.
What you want is a stable sort. One where the ordering does not change. To get a stable sort, you need for each row to be uniquely identified. I might suggest:
ORDER BY ISNULL(G.game_uploading_starts), G.game_listening_starts desc, game_id
This is guaranteed to be unique because of the group by.
I happen to think that the SQL Server documentation does the best job of explaining stable sorts:
To achieve stable results between query requests using OFFSET and
FETCH, the following conditions must be met:
The underlying data that
is used by the query must not change. That is, either the rows touched
by the query are not updated or all requests for pages from the query
are executed in a single transaction using either snapshot or
serializable transaction isolation. For more information about these
transaction isolation levels, see SET TRANSACTION ISOLATION LEVEL
(Transact-SQL).
The ORDER BY clause contains a column or combination
of columns that are guaranteed to be unique.
I realize that you are using MySQL, but the same idea applies.