MySQL索引和使用filesort

这与我最后一个问题有关 。 我在列表中创build了一个新的列,其中一个用于组合views_point (每增加100个视图)和一个用于views_pointviews_point年 – 月 – date小时)发布的date来创build一些唯一值。

这是我的新表格:

 CREATE TABLE IF NOT EXISTS `listings` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `type` tinyint(1) NOT NULL DEFAULT '1', `hash` char(32) NOT NULL, `source_id` int(10) unsigned NOT NULL, `link` varchar(255) NOT NULL, `short_link` varchar(255) NOT NULL, `cat_id` mediumint(5) NOT NULL, `title` mediumtext NOT NULL, `description` mediumtext, `content` mediumtext, `images` mediumtext, `videos` mediumtext, `views` int(10) unsigned NOT NULL DEFAULT '0', `views_point` int(10) unsigned NOT NULL DEFAULT '0', `comments` int(11) DEFAULT '0', `comments_update` int(11) NOT NULL DEFAULT '0', `editor_id` int(11) NOT NULL DEFAULT '0', `auther_name` varchar(255) DEFAULT NULL, `createdby_id` int(10) NOT NULL, `createdon` int(20) NOT NULL, `editedby_id` int(10) NOT NULL, `editedon` int(20) NOT NULL, `deleted` tinyint(1) NOT NULL, `deletedon` int(20) NOT NULL, `deletedby_id` int(10) NOT NULL, `deletedfor` varchar(255) NOT NULL, `published` tinyint(1) NOT NULL DEFAULT '1', `publishedon` int(11) unsigned NOT NULL, `publishedon_hourly` int(10) unsigned NOT NULL DEFAULT '0', `publishedby_id` int(10) NOT NULL, PRIMARY KEY (`id`), KEY `hash` (`hash`), KEY `views_point` (`views_point`), KEY `listings` (`publishedon_hourly`,`published`,`cat_id`,`source_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED AUTO_INCREMENT=365513 ; 

当我运行这样的查询:

 SELECT * FROM listings WHERE (`publishedon_hourly` BETWEEN UNIX_TIMESTAMP( '2015-09-5 00:00:00' ) AND UNIX_TIMESTAMP( '2015-10-5 12:00:00' )) AND (published =1) AND cat_id IN ( 1, 2, 3, 4, 5 ) ORDER BY by `views_point` DESC LIMIT 10 

这是伟大的,这是解释: 在这里输入图像说明

但是,当我每月更改date范围如下所示:

 SELECT * FROM listings WHERE (`publishedon_hourly` BETWEEN UNIX_TIMESTAMP( '2015-09-5 00:00:00' ) AND UNIX_TIMESTAMP( '2015-09-5 12:00:00' )) AND (published =1) AND cat_id IN ( 1, 2, 3, 4, 5 ) ORDER BY `views_point` DESC LIMIT 10 

然后查询变慢,出现文件夹。 任何人都知道原因,我该如何解决?

数据样本(来自慢速查询)

 INSERT INTO `listings` (`id`, `type`, `hash`, `source_id`, `link`, `short_link`, `cat_id`, `title`, `description`, `content`, `images`, `videos`, `views`, `views_point`, `comments`, `comments_update`, `editor_id`, `auther_name`, `createdby_id`, `createdon`, `editedby_id`, `editedon`, `deleted`, `deletedon`, `deletedby_id`, `deletedfor`, `published`, `publishedon`, `publishedon_hourly`, `publishedby_id`) VALUES (94189, 1, '44a46d128ce730c72927b19c445ab26e', 8, 'http://Larkin.com/sapiente-laboriosam-omnis-tempore-aliquam-qui-nobis', '', 5, 'And Alice was more and.', 'So they got settled down again very sadly and quietly, and.', 'Dormouse. ''Fourteenth of March, I think it so quickly that the Gryphon only answered ''Come on!'' and ran the faster, while more and more sounds of broken glass, from which she concluded that it was looking down at them, and then a voice sometimes choked with sobs, to sing this:-- ''Beautiful Soup, so rich and green, Waiting in a natural way. ''I thought you did,'' said the Dormouse, without considering at all what had become of it; and as it.', NULL, '', 200, 19700, 0, 0, 0, 'Max', 0, 1441442729, 0, 0, 0, 0, 0, '', 1, 1441442729, 1441440000, 0), (19030, 1, '3438f6a555f2ce7fdfe03cee7a52882a', 3, 'http://Romaguera.com/voluptatem-rerum-quia-sed', '', 2, 'Dodo said, ''EVERYBODY.', 'I wish I hadn''t to bring but one; Bill''s got the.', 'I wonder what they''ll do well enough; don''t be particular--Here, Bill! catch hold of this remark, and thought to herself. (Alice had no idea what Latitude or Longitude I''ve got to the confused clamour of the other queer noises, would change to dull reality--the grass would be offended again. ''Mine is a long way. So she went on. ''I do,'' Alice said nothing; she had succeeded in curving it down ''important,'' and some were birds,) ''I suppose so,''.', NULL, '', 800, 19400, 0, 0, 0, 'Antonio', 0, 1441447567, 0, 0, 0, 0, 0, '', 1, 1441447567, 1441447200, 0), (129247, 4, '87d2029a300d8b4314508786eb620a24', 10, 'http://Ledner.com/', '', 4, 'I ever saw one that.', 'The Cat seemed to be a person of authority among them,.', 'I BEG your pardon!'' she exclaimed in a natural way again. ''I wonder what was the same height as herself; and when she looked down at her feet as the question was evidently meant for her. ''I can tell you my history, and you''ll understand why it is I hate cats and dogs.'' It was all dark overhead; before her was another long passage, and the blades of grass, but she had sat down a very little! Besides, SHE''S she, and I''m sure I have dropped them, I wonder?'' As she said to herself; ''his eyes are so VERY tired of being all alone here!'' As she said to itself ''Then I''ll go round a deal.', NULL, '', 1000, 19100, 0, 0, 0, 'Drake', 0, 1441409756, 0, 0, 0, 0, 0, '', 1, 1441409756, 1441407600, 0), (264582, 2, '5e44fe417f284f42c3b10bccd9c89b14', 8, 'http://www.Dietrich.info/laboriosam-quae-eaque-aut-dolorem', '', 2, 'Alice asked in a very.', 'THINK; or is it directed to?'' said the Mock Turtle,.', 'I can listen all day to such stuff? Be off, or I''ll have you executed.'' The miserable Hatter dropped his teacup and bread-and-butter, and then unrolled the parchment scroll, and read as follows:-- ''The Queen will hear you! You see, she came upon a little of the players to be lost, as she spoke--fancy CURTSEYING as you''re falling through the wood. ''It''s the stupidest tea-party I.', NULL, '', 800, 18700, 0, 0, 0, 'Kevin', 0, 1441441192, 0, 0, 0, 0, 0, '', 1, 1441441192, 1441440000, 0), (44798, 1, '567cc77ba88c05a4a805dc667816a30c', 14, 'http://www.Hintz.com/distinctio-nulla-quia-incidunt-facere-reprehenderit-sapiente-sint.html', '', 5, 'The Cat seemed to Alice.', 'And the moral of that is--"Be what you mean,'' said Alice..', 'Alice very politely; but she felt very lonely and low-spirited. In a little faster?" said a sleepy voice behind her. ''Collar that Dormouse,'' the Queen said severely ''Who is it directed to?'' said the Footman, and began staring at the Footman''s head: it just at first, but, after watching it a violent blow underneath her chin: it had no pictures or conversations in it, ''and what is the capital of Paris, and Paris is the same thing, you know.'' ''I DON''T.', NULL, '', 300, 17600, 0, 0, 0, 'Rocio', 0, 1441442557, 0, 0, 0, 0, 0, '', 1, 1441442557, 1441440000, 0), (184472, 1, 'f852e3ed401c7c72c5a9609687385f65', 14, 'https://www.Schumm.biz/voluptatum-iure-qui-dicta-modi-est', '', 4, 'Alice replied, so.', 'I should have liked teaching it tricks very much, if--if.', 'NEVER come to the Dormouse, not choosing to notice this question, but hurriedly went on, ''What''s your name, child?'' ''My name is Alice, so please your Majesty,'' said Two, in a great thistle, to keep back the wandering hair that WOULD always get into her face. ''Wake up, Alice dear!'' said her sister; ''Why, what a dear quiet thing,'' Alice went on, spreading out the answer to shillings and pence. ''Take off your hat,'' the King had said that day. ''No, no!'' said the Gryphon. ''They can''t have anything to say, she simply bowed, and took the watch and looked at it again: but he could.', NULL, '', 900, 17600, 0, 0, 0, 'Billy', 0, 1441407837, 0, 0, 0, 0, 0, '', 1, 1441407837, 1441407600, 0), (344246, 2, '09dc73287ff642cfa2c97977dc42bc64', 6, 'http://www.Cole.com/sit-maiores-et-quam-vitae-ut-fugiat', '', 1, 'IS the use of a.', 'And when I learn music.'' ''Ah! that accounts for it,'' said.', 'Gryphon answered, very nearly carried it out loud. ''Thinking again?'' the Duchess by this time.) ''You''re nothing but a pack of cards, after all. I needn''t be so stingy about it, you know--'' ''But, it goes on "THEY ALL RETURNED FROM HIM TO YOU,"'' said Alice. ''Call it what you mean,'' the March Hare, ''that "I breathe when I breathe"!'' ''It IS the same side of WHAT? The other guests had taken his watch out of it, and talking over its head. ''Very uncomfortable for the first to speak. ''What size do you like to go and get.', NULL, '', 600, 16900, 0, 0, 0, 'Enrico', 0, 1441406107, 0, 0, 0, 0, 0, '', 1, 1441406107, 1441404000, 0), (19169, 1, '116c443b5709e870248c93358f9a328e', 12, 'http://www.Gleason.com/et-vero-optio-exercitationem-aliquid-optio-consectetur', '', 4, 'Let this be a lesson to.', 'Sir, With no jury or judge, would be very likely to eat.', 'I wonder who will put on your head-- Do you think I can find them.'' As she said this, she was quite out of sight before the end of every line: ''Speak roughly to your little boy, And beat him when he sneezes; For he can EVEN finish, if he had never heard of such a subject! Our family always HATED cats: nasty, low, vulgar things! Don''t let him know she liked them best, For this must ever be A secret, kept from all the creatures wouldn''t be so kind,'' Alice replied, so eagerly that the way I want to get very tired of being upset, and their curls got entangled together. Alice was not a regular rule: you invented it just grazed his nose, you know?'' ''It''s the thing Mock Turtle would be only.', NULL, '', 700, 16800, 0, 0, 0, 'Unique', 0, 1441407961, 0, 0, 0, 0, 0, '', 1, 1441407961, 1441407600, 0), (192679, 1, '06a33747b5c95799034630e578e53dc5', 10, 'http://www.Pouros.com/qui-id-molestias-non-dolores-non', '', 5, 'Rabbit just under the.', 'KNOW IT TO BE TRUE--" that''s the jury-box,'' thought Alice,.', 'Mock Turtle, who looked at Two. Two began in a hoarse, feeble voice: ''I heard every word you fellows were saying.'' ''Tell us a story.'' ''I''m afraid I can''t tell you how it was too dark to see what I should say "With what porpoise?"'' ''Don''t you mean by that?'' said the King; and as it was indeed: she was now more than Alice could not make out exactly what they WILL do next! As for pulling me out of court! Suppress him! Pinch him! Off with his head!"'' ''How dreadfully savage!'' exclaimed Alice. ''That''s the first witness,'' said the Duchess. ''Everything''s got a moral, if only you can find it.'' And she squeezed herself up and ran the faster, while more and more faintly came, carried on the end of every line:.', NULL, '', 800, 15900, 0, 0, 0, 'Gene', 0, 1441414720, 0, 0, 0, 0, 0, '', 1, 1441414720, 1441411200, 0), (251878, 4, '3eafacc53f86c8492c309ca2772fbfe9', 5, 'http://www.Schinner.info/tempora-et-est-qui-nulla', '', 2, 'NOT!'' cried the Mouse,.', 'Twinkle, twinkle--"'' Here the Queen till she heard the.', 'Alice and all of them even when they hit her; and the sounds will take care of the gloves, and she dropped it hastily, just in time to begin at HIS time of life. The King''s argument was, that she had forgotten the Duchess to play croquet with the Dormouse. ''Write that down,'' the King added in an undertone to the fifth bend, I think?'' ''I had NOT!'' cried the Mouse, sharply and very neatly and simply arranged; the only difficulty was, that if something wasn''t done about it in less than a pig, my dear,'' said Alice, a little wider. ''Come, it''s pleased so far,'' said the Gryphon. ''Do you play croquet with the glass table and the King hastily said, and went by without noticing her. Then followed the Knave ''Turn them over!'' The Knave of.', NULL, '', 500, 15900, 0, 0, 0, 'Demarcus', 0, 1441414681, 0, 0, 0, 0, 0, '', 1, 1441414681, 1441411200, 0); 

在这里输入图像说明

看来某种新闻数据库,所以试着想想每个月都要做一些新闻存档。

想想这个解决scheme,这不是最好的,但可能有帮助

  • 将这些列添加到列表
    • publishedmonth tinyint(2)UNSIGNED NOT NULL DEFAULT'0'
    • publishedyear tinyint(2)UNSIGNED NOT NULL DEFAULT'0'
    • publishedminute mediumint(6)UNSIGNED NOT NULL DEFAULT'0'
  • 将此INDEXING KEY添加到列表

    • ADD KEY published_month (publishedmonth,publishedyear,publishedminute)
  • 插入期间使用PHP代码中的这些值

    • publishedmonth会有date('n')
    • 发表date('y')
    • 发表date('jHi')会有date('jHi')

转储大量的logging,然后testing这个查询

 SELECT * FROM listings WHERE publishedmonth = 2 AND publishedyear = 17 ORDER BY publishedminute 

在你的第一个查询中,ORDER BY是使用views_point INDEX完成的,因为它被用在查询的WHERE部分,因此在MySQL中可以用于sorting。

在第二个查询中,MySQL使用不同的索引listing_pcs来parsingWHERE部分。 这不能用来满足ORDER BY条件。 MySQL使用filesort,如果索引不能被使用,这是最好的select。

如果索引与WHERE条件中使用的相同,MySQL只使用索引进行sorting。 这是手册的意思是:

在某些情况下,MySQL不能使用索引来parsingORDER BY,虽然它仍然使用索引来查找匹配WHERE子句的行。 这些情况包括以下内容:

用于提取行的键不同于在ORDER BY中使用的键:

 SELECT * FROM t1 WHERE key2=constant ORDER BY key1; 

所以,你可以做什么:

  1. 尝试增加你的sort_buffer_sizeconfiguration选项使文件尽可能有效。 大的结果对于sorting缓冲区来说太大了,这导致MySQL将sorting分解成块,这比较慢。

  2. 强制MySQLselect不同的索引。 值得注意的是,不同的MySQL版本select不同的默认索引。 例如,版本5.1是非常糟糕的,因为查询优化器已经为这个版本大量重写,需要大量的改进。 版本5.6是相当不错的。

     SELECT * FROM listings FORCE INDEX (views_point) WHERE (`publishedon_hourly` BETWEEN UNIX_TIMESTAMP( '2015-09-5 00:00:00' ) AND UNIX_TIMESTAMP( '2015-09-5 12:00:00' )) AND (published =1) AND cat_id IN ( 1, 2, 3, 4, 5 ) ORDER BY `views_point` DESC LIMIT 10 

非常奇怪的行为。 很难views_point为什么views_point不会被用于sorting操作而不会看到有问题的数据。 你可以尝试给MySQL一个索引提示,使用views_pointsorting。

 SELECT * FROM listings USE INDEX FOR ORDER BY (`views_point`) WHERE ( `publishedon_hourly` BETWEEN UNIX_TIMESTAMP( '2015-09-5 00:00:00' ) AND UNIX_TIMESTAMP( '2015-09-5 12:00:00' ) ) AND (published =1) AND cat_id IN ( 1, 2, 3, 4, 5 ) ORDER BY `views_point` DESC LIMIT 10 
  • EXPLAIN表示listings_pcs ,但SHOW CREATE TABLE不会列出该索引。 我们错过了什么吗?
  • 如果只需要几列,请不要使用SELECT * 。 特别是在查询期间, TEXT列将阻止一种forms的性能加速。
  • 查询部分查询的子查询通常会显示出来。 但是,对于你的情况(大量MEDIUMTEXT被提取,并使用LIMIT ),首先获取子查询中的ID,然后获取庞大的列可能是有效的。 (“懒惰eval”)见下文。
  • 范围值( publishedon_hourly )在索引中最好,而不是第一个。
  • =列( published )开始索引通常是最好的。
  • 优化器有时会错误地selectORDER BY而不是WHERE 。 (在你的情况下都不是很有成效)。
  • INDEX(published, views_point) 可能会避免sorting,同时帮助一些与WHERE
  • 拥有一个始终在查询中进行testing的标志( published )会增加架构的复杂性和低效率。
  • BETWEEN是包容性的,所以第二个查询实际上是扫描12小时加一秒。
  • 将date分成年,月,日通常比帮助更难受。
  • 不要将sort_buffer_size设置为大于RAM的1%。 否则,您可能会遇到其他问题。
  • FORCE INDEX可能对今天有帮助,但是当常数变化时,明天就会受到伤害。 买者自负。
  • 将“click_count”或“likes”或“upvotes”放在单独的表格中通常会更好。 这将快速变化的计数器从庞大的,相对静态的数据中分离出来。 因此,两者之间的干扰较less。
  • 如果你这样做,只需从计数器表中删除未发布的行,从而简化了几件事情。
  • 大多数人诋毁filesort ,但通常是其他的东西是恶棍 – 你的情况,行数和大小。
  • 请提供EXPLAIN FORMAT=JSON SELECT ... ; 可能会有一些有趣的线索。
  • 您的发现足够奇怪,可以在bugs.mysql.com上填写错误。

我将按照给定的顺序添加这些索引,并查看Optimizerselect的内容:

 INDEX(published, views_point) -- aiming at the ORDER BY, plus picking up '=' INDEX(published, cat_id, publishedon_hourly) -- possibly the best for WHERE 

或者,也许,“懒惰的评价”

 SELECT L.* FROM listings AS L JOIN ( SELECT id FROM listings WHERE `publishedon_hourly` BETWEEN UNIX_TIMESTAMP(...) AND UNIX_TIMESTAMP(...) AND published = 1 AND cat_id IN ( 1, 2, 3, 4, 5 ) ORDER BY `views_point` DESC LIMIT 10 ) AS s ON L.id = s.id ORDER BY views_point DESC -- with INDEX(published, cat_id, publishedon_hourly, views_point, id) 

笔记:

  • 子查询将是“使用索引”; 就是这个指标正在覆盖。
  • 将有两个文件sorting。 一个在子查询中,但是从索引开始,而不是庞大的文本。 而一个只有10行,虽然笨重。

查询优化器并不完美。 这是一个错误的决定。 这发生在一些边界线情况下。 如果表中的数据会发生变化,那么可能会使用其他索引并运行更快的查询。

你不会等待它,你可以改变你的listing_pcs索引。 它有source_id,但你没有使用。 那么为什么不用view_points来代替呢?

 KEY `listings` (`publishedon_hourly`,`published`,`point`,`cat_id`) 

也使用tinyint(1)没有太多的使用速度或节省空间。 它仍然需要一个完整的字节。 同样的mediumint(5)需要3个字节。 将deletedtypecatidpublished到一列中,并将索引放在该列上。