Note that there are some explanatory texts on larger screens.

plurals
  1. POOrdering in MySQL Bogs Down
    primarykey
    data
    text
    <p>I've been working on a small Perl program that works with a table of articles, displaying them to the user if they have not been already read. It has been working nicely and it has been quite speedy, overall. However, this afternoon, the performance has degraded from fast enough that I wasn't worried about optimizing the query to a glacial 3-4 seconds per query. To select articles, I present this query:</p> <pre><code>SELECT channelitem.ciid, channelitem.cid, name, description, url, creationdate, author FROM `channelitem` WHERE ciid NOT IN ( SELECT ciid FROM `uninet_channelitem_read` WHERE uid = '1030' ) AND ( cid =117 OR cid =308 OR cid =310 ) ORDER BY `channelitem`.`creationdate` DESC LIMIT 0 , 100 </code></pre> <p>The list of possible cid's varies and could be quite a bit more. In any case, I noted that about 2-3 seconds of the total time to make the query is devoted to "ORDER BY." If I remove that, it only takes about a half second to give me the query back. If I drop the subquery, the performance goes back to normal... but the subquery didn't seem to be problematic until just this afternoon, after working fine for a week or so.</p> <p>Any ideas what could be slowing it down so much? What might I do to try to get the performance back up to snuff? The table being queried has 45,000 rows. The subquery's table has fewer than 3,000 rows at present.</p> <p><em>Update:</em> Incidentally, if anyone has suggestions on how to do multiple queries or some other technique that would be more efficient to accomplish what I am trying to do, I am all ears. I'm really puzzled how to solve the problem at this point. Can I somehow apply the order by before the join to make it apply to the real table and not the derived table? Would that be more efficient?</p> <p>Here is the latest version of the query, derived from suggestions from @Gordon, below</p> <pre><code>SELECT channelitem.ciid, channelitem.cid, name, description, url, creationdate, author FROM `channelitem` LEFT JOIN ( SELECT ciid, dateRead FROM `uninet_channelitem_read` WHERE uid = '1030' )alreadyRead ON channelitem.ciid = alreadyRead.ciid WHERE ( alreadyRead.ciid IS NULL ) AND `cid` IN ( 6648, 329, 323, 6654, 6647 ) ORDER BY `channelitem`.`creationdate` DESC LIMIT 0 , 100 </code></pre> <p>Also, I should mention what my db structure looks like with regards to these two tables -- maybe someone can spot something odd about the structure:</p> <pre><code>CREATE TABLE IF NOT EXISTS `channelitem` ( `newsversion` int(11) NOT NULL DEFAULT '0', `cid` int(11) NOT NULL DEFAULT '0', `ciid` int(11) NOT NULL AUTO_INCREMENT, `description` text CHARACTER SET utf8 COLLATE utf8_unicode_ci, `url` varchar(222) DEFAULT NULL, `creationdate` datetime DEFAULT NULL, `urgent` varchar(10) DEFAULT NULL, `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL, `lastchanged` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `author` varchar(255) NOT NULL, PRIMARY KEY (`ciid`), KEY `newsversion` (`newsversion`), KEY `cid` (`cid`), KEY `creationdate` (`creationdate`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1638554365 ; CREATE TABLE IF NOT EXISTS `uninet_channelitem_read` ( `ciid` int(11) NOT NULL, `uid` int(11) NOT NULL, `dateRead` datetime NOT NULL, PRIMARY KEY (`ciid`,`uid`), KEY `ciid` (`ciid`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload