From 3019d3972932931d9c4a14bec4183b232355cdcf Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sun, 11 Oct 2009 21:59:34 -0700 Subject: [PATCH 01/33] The main patch for WL#24: "index_merge: fair choice between index_merge union and range access" mysql-test/include/world.inc: A new include file to upload the world database. mysql-test/include/world_schema.inc: A new include file to create tables of the world database. mysql-test/r/index_merge_myisam.result: The results for test cases testing the optimizations added in WL#24 for MyISAM. mysql-test/r/range_vs_index_merge.result: The results for test cases testing the optimizations added in WL#24 for InnoDB. mysql-test/t/range_vs_index_merge.test: Test cases to test the optimizations added in WL#24 for MyISAM. mysql-test/t/range_vs_index_merge_innodb.test: Test cases to test the optimizations added in WL#24 for InnoDB. sql/sql_list.h: Fixed a bug that did not allow adding a non-empty list to an empty list. --- mysql-test/include/world.inc | 5343 +++++++++++++++++ mysql-test/include/world_schema.inc | 25 + mysql-test/r/index_merge_myisam.result | 6 +- mysql-test/r/range_vs_index_merge.result | 1328 ++++ .../r/range_vs_index_merge_innodb.result | 1330 ++++ mysql-test/t/range_vs_index_merge.test | 805 +++ mysql-test/t/range_vs_index_merge_innodb.test | 7 + sql/opt_range.cc | 1644 ++++- sql/sql_list.h | 8 + 9 files changed, 10165 insertions(+), 331 deletions(-) create mode 100755 mysql-test/include/world.inc create mode 100755 mysql-test/include/world_schema.inc create mode 100755 mysql-test/r/range_vs_index_merge.result create mode 100755 mysql-test/r/range_vs_index_merge_innodb.result create mode 100755 mysql-test/t/range_vs_index_merge.test create mode 100755 mysql-test/t/range_vs_index_merge_innodb.test diff --git a/mysql-test/include/world.inc b/mysql-test/include/world.inc new file mode 100755 index 00000000000..eae6556c422 --- /dev/null +++ b/mysql-test/include/world.inc @@ -0,0 +1,5343 @@ +# +# Populate the world database +# + +# Table Country + +INSERT INTO Country VALUES +('AFG','Afghanistan',652090.00,22720000,1), +('NLD','Netherlands',41526.00,15864000,5), +('ANT','Netherlands Antilles',800.00,217000,33), +('ALB','Albania',28748.00,3401200,34), +('DZA','Algeria',2381741.00,31471000,35), +('ASM','American Samoa',199.00,68000,54), +('AND','Andorra',468.00,78000,55), +('AGO','Angola',1246700.00,12878000,56), +('AIA','Anguilla',96.00,8000,62), +('ATG','Antigua and Barbuda',442.00,68000,63), +('ARE','United Arab Emirates',83600.00,2441000,65), +('ARG','Argentina',2780400.00,37032000,69), +('ARM','Armenia',29800.00,3520000,126), +('ABW','Aruba',193.00,103000,129), +('AUS','Australia',7741220.00,18886000,135), +('AZE','Azerbaijan',86600.00,7734000,144), +('BHS','Bahamas',13878.00,307000,148), +('BHR','Bahrain',694.00,617000,149), +('BGD','Bangladesh',143998.00,129155000,150), +('BRB','Barbados',430.00,270000,174), +('BEL','Belgium',30518.00,10239000,179), +('BLZ','Belize',22696.00,241000,185), +('BEN','Benin',112622.00,6097000,187), +('BMU','Bermuda',53.00,65000,191), +('BTN','Bhutan',47000.00,2124000,192), +('BOL','Bolivia',1098581.00,8329000,194), +('BIH','Bosnia and Herzegovina',51197.00,3972000,201), +('BWA','Botswana',581730.00,1622000,204), +('BRA','Brazil',8547403.00,170115000,211), +('GBR','United Kingdom',242900.00,59623400,456), +('VGB','Virgin Islands, British',151.00,21000,537), +('BRN','Brunei',5765.00,328000,538), +('BGR','Bulgaria',110994.00,8190900,539), +('BFA','Burkina Faso',274000.00,11937000,549), +('BDI','Burundi',27834.00,6695000,552), +('CYM','Cayman Islands',264.00,38000,553), +('CHL','Chile',756626.00,15211000,554), +('COK','Cook Islands',236.00,20000,583), +('CRI','Costa Rica',51100.00,4023000,584), +('DJI','Djibouti',23200.00,638000,585), +('DMA','Dominica',751.00,71000,586), +('DOM','Dominican Republic',48511.00,8495000,587), +('ECU','Ecuador',283561.00,12646000,594), +('EGY','Egypt',1001449.00,68470000,608), +('SLV','El Salvador',21041.00,6276000,645), +('ERI','Eritrea',117600.00,3850000,652), +('ESP','Spain',505992.00,39441700,653), +('ZAF','South Africa',1221037.00,40377000,716), +('ETH','Ethiopia',1104300.00,62565000,756), +('FLK','Falkland Islands',12173.00,2000,763), +('FJI','Fiji Islands',18274.00,817000,764), +('PHL','Philippines',300000.00,75967000,766), +('FRO','Faroe Islands',1399.00,43000,901), +('GAB','Gabon',267668.00,1226000,902), +('GMB','Gambia',11295.00,1305000,904), +('GEO','Georgia',69700.00,4968000,905), +('GHA','Ghana',238533.00,20212000,910), +('GIB','Gibraltar',6.00,25000,915), +('GRD','Grenada',344.00,94000,916), +('GRL','Greenland',2166090.00,56000,917), +('GLP','Guadeloupe',1705.00,456000,919), +('GUM','Guam',549.00,168000,921), +('GTM','Guatemala',108889.00,11385000,922), +('GIN','Guinea',245857.00,7430000,926), +('GNB','Guinea-Bissau',36125.00,1213000,927), +('GUY','Guyana',214969.00,861000,928), +('HTI','Haiti',27750.00,8222000,929), +('HND','Honduras',112088.00,6485000,933), +('HKG','Hong Kong',1075.00,6782000,937), +('SJM','Svalbard and Jan Mayen',62422.00,3200,938), +('IDN','Indonesia',1904569.00,212107000,939), +('IND','India',3287263.00,1013662000,1109), +('IRQ','Iraq',438317.00,23115000,1365), +('IRN','Iran',1648195.00,67702000,1380), +('IRL','Ireland',70273.00,3775100,1447), +('ISL','Iceland',103000.00,279000,1449), +('ISR','Israel',21056.00,6217000,1450), +('ITA','Italy',301316.00,57680000,1464), +('TMP','East Timor',14874.00,885000,1522), +('AUT','Austria',83859.00,8091800,1523), +('JAM','Jamaica',10990.00,2583000,1530), +('JPN','Japan',377829.00,126714000,1532), +('YEM','Yemen',527968.00,18112000,1780), +('JOR','Jordan',88946.00,5083000,1786), +('CXR','Christmas Island',135.00,2500,1791), +('YUG','Yugoslavia',102173.00,10640000,1792), +('KHM','Cambodia',181035.00,11168000,1800), +('CMR','Cameroon',475442.00,15085000,1804), +('CAN','Canada',9970610.00,31147000,1822), +('CPV','Cape Verde',4033.00,428000,1859), +('KAZ','Kazakstan',2724900.00,16223000,1864), +('KEN','Kenya',580367.00,30080000,1881), +('CAF','Central African Republic',622984.00,3615000,1889), +('CHN','China',9572900.00,1277558000,1891), +('KGZ','Kyrgyzstan',199900.00,4699000,2253), +('KIR','Kiribati',726.00,83000,2256), +('COL','Colombia',1138914.00,42321000,2257), +('COM','Comoros',1862.00,578000,2295), +('COG','Congo',342000.00,2943000,2296), +('COD','Congo, The Democratic Republic of the',2344858.00,51654000,2298), +('CCK','Cocos (Keeling) Islands',14.00,600,2317), +('PRK','North Korea',120538.00,24039000,2318), +('KOR','South Korea',99434.00,46844000,2331), +('GRC','Greece',131626.00,10545700,2401), +('HRV','Croatia',56538.00,4473000,2409), +('CUB','Cuba',110861.00,11201000,2413), +('KWT','Kuwait',17818.00,1972000,2429), +('CYP','Cyprus',9251.00,754700,2430), +('LAO','Laos',236800.00,5433000,2432), +('LVA','Latvia',64589.00,2424200,2434), +('LSO','Lesotho',30355.00,2153000,2437), +('LBN','Lebanon',10400.00,3282000,2438), +('LBR','Liberia',111369.00,3154000,2440), +('LBY','Libyan Arab Jamahiriya',1759540.00,5605000,2441), +('LIE','Liechtenstein',160.00,32300,2446), +('LTU','Lithuania',65301.00,3698500,2447), +('LUX','Luxembourg',2586.00,435700,2452), +('ESH','Western Sahara',266000.00,293000,2453), +('MAC','Macao',18.00,473000,2454), +('MDG','Madagascar',587041.00,15942000,2455), +('MKD','Macedonia',25713.00,2024000,2460), +('MWI','Malawi',118484.00,10925000,2462), +('MDV','Maldives',298.00,286000,2463), +('MYS','Malaysia',329758.00,22244000,2464), +('MLI','Mali',1240192.00,11234000,2482), +('MLT','Malta',316.00,380200,2484), +('MAR','Morocco',446550.00,28351000,2486), +('MHL','Marshall Islands',181.00,64000,2507), +('MTQ','Martinique',1102.00,395000,2508), +('MRT','Mauritania',1025520.00,2670000,2509), +('MUS','Mauritius',2040.00,1158000,2511), +('MYT','Mayotte',373.00,149000,2514), +('MEX','Mexico',1958201.00,98881000,2515), +('FSM','Micronesia, Federated States of',702.00,119000,2689), +('MDA','Moldova',33851.00,4380000,2690), +('MCO','Monaco',1.50,34000,2695), +('MNG','Mongolia',1566500.00,2662000,2696), +('MSR','Montserrat',102.00,11000,2697), +('MOZ','Mozambique',801590.00,19680000,2698), +('MMR','Myanmar',676578.00,45611000,2710), +('NAM','Namibia',824292.00,1726000,2726), +('NRU','Nauru',21.00,12000,2728), +('NPL','Nepal',147181.00,23930000,2729), +('NIC','Nicaragua',130000.00,5074000,2734), +('NER','Niger',1267000.00,10730000,2738), +('NGA','Nigeria',923768.00,111506000,2754), +('NIU','Niue',260.00,2000,2805), +('NFK','Norfolk Island',36.00,2000,2806), +('NOR','Norway',323877.00,4478500,2807), +('CIV','Côte d’Ivoire',322463.00,14786000,2814), +('OMN','Oman',309500.00,2542000,2821), +('PAK','Pakistan',796095.00,156483000,2831), +('PLW','Palau',459.00,19000,2881), +('PAN','Panama',75517.00,2856000,2882), +('PNG','Papua New Guinea',462840.00,4807000,2884), +('PRY','Paraguay',406752.00,5496000,2885), +('PER','Peru',1285216.00,25662000,2890), +('PCN','Pitcairn',49.00,50,2912), +('MNP','Northern Mariana Islands',464.00,78000,2913), +('PRT','Portugal',91982.00,9997600,2914), +('PRI','Puerto Rico',8875.00,3869000,2919), +('POL','Poland',323250.00,38653600,2928), +('GNQ','Equatorial Guinea',28051.00,453000,2972), +('QAT','Qatar',11000.00,599000,2973), +('FRA','France',551500.00,59225700,2974), +('GUF','French Guiana',90000.00,181000,3014), +('PYF','French Polynesia',4000.00,235000,3016), +('REU','Réunion',2510.00,699000,3017), +('ROM','Romania',238391.00,22455500,3018), +('RWA','Rwanda',26338.00,7733000,3047), +('SWE','Sweden',449964.00,8861400,3048), +('SHN','Saint Helena',314.00,6000,3063), +('KNA','Saint Kitts and Nevis',261.00,38000,3064), +('LCA','Saint Lucia',622.00,154000,3065), +('VCT','Saint Vincent and the Grenadines',388.00,114000,3066), +('SPM','Saint Pierre and Miquelon',242.00,7000,3067), +('DEU','Germany',357022.00,82164700,3068), +('SLB','Solomon Islands',28896.00,444000,3161), +('ZMB','Zambia',752618.00,9169000,3162), +('WSM','Samoa',2831.00,180000,3169), +('SMR','San Marino',61.00,27000,3171), +('STP','Sao Tome and Principe',964.00,147000,3172), +('SAU','Saudi Arabia',2149690.00,21607000,3173), +('SEN','Senegal',196722.00,9481000,3198), +('SYC','Seychelles',455.00,77000,3206), +('SLE','Sierra Leone',71740.00,4854000,3207), +('SGP','Singapore',618.00,3567000,3208), +('SVK','Slovakia',49012.00,5398700,3209), +('SVN','Slovenia',20256.00,1987800,3212), +('SOM','Somalia',637657.00,10097000,3214), +('LKA','Sri Lanka',65610.00,18827000,3217), +('SDN','Sudan',2505813.00,29490000,3225), +('FIN','Finland',338145.00,5171300,3236), +('SUR','Suriname',163265.00,417000,3243), +('SWZ','Swaziland',17364.00,1008000,3244), +('CHE','Switzerland',41284.00,7160400,3248), +('SYR','Syria',185180.00,16125000,3250), +('TJK','Tajikistan',143100.00,6188000,3261), +('TWN','Taiwan',36188.00,22256000,3263), +('TZA','Tanzania',883749.00,33517000,3306), +('DNK','Denmark',43094.00,5330000,3315), +('THA','Thailand',513115.00,61399000,3320), +('TGO','Togo',56785.00,4629000,3332), +('TKL','Tokelau',12.00,2000,3333), +('TON','Tonga',650.00,99000,3334), +('TTO','Trinidad and Tobago',5130.00,1295000,3336), +('TCD','Chad',1284000.00,7651000,3337), +('CZE','Czech Republic',78866.00,10278100,3339), +('TUN','Tunisia',163610.00,9586000,3349), +('TUR','Turkey',774815.00,66591000,3358), +('TKM','Turkmenistan',488100.00,4459000,3419), +('TCA','Turks and Caicos Islands',430.00,17000,3423), +('TUV','Tuvalu',26.00,12000,3424), +('UGA','Uganda',241038.00,21778000,3425), +('UKR','Ukraine',603700.00,50456000,3426), +('HUN','Hungary',93030.00,10043200,3483), +('URY','Uruguay',175016.00,3337000,3492), +('NCL','New Caledonia',18575.00,214000,3493), +('NZL','New Zealand',270534.00,3862000,3499), +('UZB','Uzbekistan',447400.00,24318000,3503), +('BLR','Belarus',207600.00,10236000,3520), +('WLF','Wallis and Futuna',200.00,15000,3536), +('VUT','Vanuatu',12189.00,190000,3537), +('VAT','Holy See (Vatican City State)',0.40,1000,3538), +('VEN','Venezuela',912050.00,24170000,3539), +('RUS','Russian Federation',17075400.00,146934000,3580), +('VNM','Vietnam',331689.00,79832000,3770), +('EST','Estonia',45227.00,1439200,3791), +('USA','United States',9363520.00,278357000,3813), +('VIR','Virgin Islands, U.S.',347.00,93000,4067), +('ZWE','Zimbabwe',390757.00,11669000,4068), +('PSE','Palestine',6257.00,3101000,4074), +('ATA','Antarctica',13120000.00,0,NULL), +('BVT','Bouvet Island',59.00,0,NULL), +('IOT','British Indian Ocean Territory',78.00,0,NULL), +('SGS','South Georgia and the South Sandwich Islands',3903.00,0,NULL), +('HMD','Heard Island and McDonald Islands',359.00,0,NULL), +('ATF','French Southern territories',7780.00,0,NULL), +('UMI','United States Minor Outlying Islands',16.00,0,NULL); + +# Table City + +INSERT INTO City VALUES +(1,'Kabul','AFG',1780000), +(2,'Qandahar','AFG',237500), +(3,'Herat','AFG',186800), +(4,'Mazar-e-Sharif','AFG',127800), +(5,'Amsterdam','NLD',731200), +(6,'Rotterdam','NLD',593321), +(7,'Haag','NLD',440900), +(8,'Utrecht','NLD',234323), +(9,'Eindhoven','NLD',201843), +(10,'Tilburg','NLD',193238), +(11,'Groningen','NLD',172701), +(12,'Breda','NLD',160398), +(13,'Apeldoorn','NLD',153491), +(14,'Nijmegen','NLD',152463), +(15,'Enschede','NLD',149544), +(16,'Haarlem','NLD',148772), +(17,'Almere','NLD',142465), +(18,'Arnhem','NLD',138020), +(19,'Zaanstad','NLD',135621), +(20,'´s-Hertogenbosch','NLD',129170), +(21,'Amersfoort','NLD',126270), +(22,'Maastricht','NLD',122087), +(23,'Dordrecht','NLD',119811), +(24,'Leiden','NLD',117196), +(25,'Haarlemmermeer','NLD',110722), +(26,'Zoetermeer','NLD',110214), +(27,'Emmen','NLD',105853), +(28,'Zwolle','NLD',105819), +(29,'Ede','NLD',101574), +(30,'Delft','NLD',95268), +(31,'Heerlen','NLD',95052), +(32,'Alkmaar','NLD',92713), +(33,'Willemstad','ANT',2345), +(34,'Tirana','ALB',270000), +(35,'Alger','DZA',2168000), +(36,'Oran','DZA',609823), +(37,'Constantine','DZA',443727), +(38,'Annaba','DZA',222518), +(39,'Batna','DZA',183377), +(40,'Sétif','DZA',179055), +(41,'Sidi Bel Abbès','DZA',153106), +(42,'Skikda','DZA',128747), +(43,'Biskra','DZA',128281), +(44,'Blida (el-Boulaida)','DZA',127284), +(45,'Béjaïa','DZA',117162), +(46,'Mostaganem','DZA',115212), +(47,'Tébessa','DZA',112007), +(48,'Tlemcen (Tilimsen)','DZA',110242), +(49,'Béchar','DZA',107311), +(50,'Tiaret','DZA',100118), +(51,'Ech-Chleff (el-Asnam)','DZA',96794), +(52,'Ghardaïa','DZA',89415), +(53,'Tafuna','ASM',5200), +(54,'Fagatogo','ASM',2323), +(55,'Andorra la Vella','AND',21189), +(56,'Luanda','AGO',2022000), +(57,'Huambo','AGO',163100), +(58,'Lobito','AGO',130000), +(59,'Benguela','AGO',128300), +(60,'Namibe','AGO',118200), +(61,'South Hill','AIA',961), +(62,'The Valley','AIA',595), +(63,'Saint John´s','ATG',24000), +(64,'Dubai','ARE',669181), +(65,'Abu Dhabi','ARE',398695), +(66,'Sharja','ARE',320095), +(67,'al-Ayn','ARE',225970), +(68,'Ajman','ARE',114395), +(69,'Buenos Aires','ARG',2982146), +(70,'La Matanza','ARG',1266461), +(71,'Córdoba','ARG',1157507), +(72,'Rosario','ARG',907718), +(73,'Lomas de Zamora','ARG',622013), +(74,'Quilmes','ARG',559249), +(75,'Almirante Brown','ARG',538918), +(76,'La Plata','ARG',521936), +(77,'Mar del Plata','ARG',512880), +(78,'San Miguel de Tucumán','ARG',470809), +(79,'Lanús','ARG',469735), +(80,'Merlo','ARG',463846), +(81,'General San Martín','ARG',422542), +(82,'Salta','ARG',367550), +(83,'Moreno','ARG',356993), +(84,'Santa Fé','ARG',353063), +(85,'Avellaneda','ARG',353046), +(86,'Tres de Febrero','ARG',352311), +(87,'Morón','ARG',349246), +(88,'Florencio Varela','ARG',315432), +(89,'San Isidro','ARG',306341), +(90,'Tigre','ARG',296226), +(91,'Malvinas Argentinas','ARG',290335), +(92,'Vicente López','ARG',288341), +(93,'Berazategui','ARG',276916), +(94,'Corrientes','ARG',258103), +(95,'San Miguel','ARG',248700), +(96,'Bahía Blanca','ARG',239810), +(97,'Esteban Echeverría','ARG',235760), +(98,'Resistencia','ARG',229212), +(99,'José C. Paz','ARG',221754), +(100,'Paraná','ARG',207041), +(101,'Godoy Cruz','ARG',206998), +(102,'Posadas','ARG',201273), +(103,'Guaymallén','ARG',200595), +(104,'Santiago del Estero','ARG',189947), +(105,'San Salvador de Jujuy','ARG',178748), +(106,'Hurlingham','ARG',170028), +(107,'Neuquén','ARG',167296), +(108,'Ituzaingó','ARG',158197), +(109,'San Fernando','ARG',153036), +(110,'Formosa','ARG',147636), +(111,'Las Heras','ARG',145823), +(112,'La Rioja','ARG',138117), +(113,'San Fernando del Valle de Cata','ARG',134935), +(114,'Río Cuarto','ARG',134355), +(115,'Comodoro Rivadavia','ARG',124104), +(116,'Mendoza','ARG',123027), +(117,'San Nicolás de los Arroyos','ARG',119302), +(118,'San Juan','ARG',119152), +(119,'Escobar','ARG',116675), +(120,'Concordia','ARG',116485), +(121,'Pilar','ARG',113428), +(122,'San Luis','ARG',110136), +(123,'Ezeiza','ARG',99578), +(124,'San Rafael','ARG',94651), +(125,'Tandil','ARG',91101), +(126,'Yerevan','ARM',1248700), +(127,'Gjumri','ARM',211700), +(128,'Vanadzor','ARM',172700), +(129,'Oranjestad','ABW',29034), +(130,'Sydney','AUS',3276207), +(131,'Melbourne','AUS',2865329), +(132,'Brisbane','AUS',1291117), +(133,'Perth','AUS',1096829), +(134,'Adelaide','AUS',978100), +(135,'Canberra','AUS',322723), +(136,'Gold Coast','AUS',311932), +(137,'Newcastle','AUS',270324), +(138,'Central Coast','AUS',227657), +(139,'Wollongong','AUS',219761), +(140,'Hobart','AUS',126118), +(141,'Geelong','AUS',125382), +(142,'Townsville','AUS',109914), +(143,'Cairns','AUS',92273), +(144,'Baku','AZE',1787800), +(145,'Gäncä','AZE',299300), +(146,'Sumqayit','AZE',283000), +(147,'Mingäçevir','AZE',93900), +(148,'Nassau','BHS',172000), +(149,'al-Manama','BHR',148000), +(150,'Dhaka','BGD',3612850), +(151,'Chittagong','BGD',1392860), +(152,'Khulna','BGD',663340), +(153,'Rajshahi','BGD',294056), +(154,'Narayanganj','BGD',202134), +(155,'Rangpur','BGD',191398), +(156,'Mymensingh','BGD',188713), +(157,'Barisal','BGD',170232), +(158,'Tungi','BGD',168702), +(159,'Jessore','BGD',139710), +(160,'Comilla','BGD',135313), +(161,'Nawabganj','BGD',130577), +(162,'Dinajpur','BGD',127815), +(163,'Bogra','BGD',120170), +(164,'Sylhet','BGD',117396), +(165,'Brahmanbaria','BGD',109032), +(166,'Tangail','BGD',106004), +(167,'Jamalpur','BGD',103556), +(168,'Pabna','BGD',103277), +(169,'Naogaon','BGD',101266), +(170,'Sirajganj','BGD',99669), +(171,'Narsinghdi','BGD',98342), +(172,'Saidpur','BGD',96777), +(173,'Gazipur','BGD',96717), +(174,'Bridgetown','BRB',6070), +(175,'Antwerpen','BEL',446525), +(176,'Gent','BEL',224180), +(177,'Charleroi','BEL',200827), +(178,'Liège','BEL',185639), +(179,'Bruxelles [Brussel]','BEL',133859), +(180,'Brugge','BEL',116246), +(181,'Schaerbeek','BEL',105692), +(182,'Namur','BEL',105419), +(183,'Mons','BEL',90935), +(184,'Belize City','BLZ',55810), +(185,'Belmopan','BLZ',7105), +(186,'Cotonou','BEN',536827), +(187,'Porto-Novo','BEN',194000), +(188,'Djougou','BEN',134099), +(189,'Parakou','BEN',103577), +(190,'Saint George','BMU',1800), +(191,'Hamilton','BMU',1200), +(192,'Thimphu','BTN',22000), +(193,'Santa Cruz de la Sierra','BOL',935361), +(194,'La Paz','BOL',758141), +(195,'El Alto','BOL',534466), +(196,'Cochabamba','BOL',482800), +(197,'Oruro','BOL',223553), +(198,'Sucre','BOL',178426), +(199,'Potosí','BOL',140642), +(200,'Tarija','BOL',125255); +INSERT INTO City VALUES +(201,'Sarajevo','BIH',360000), +(202,'Banja Luka','BIH',143079), +(203,'Zenica','BIH',96027), +(204,'Gaborone','BWA',213017), +(205,'Francistown','BWA',101805), +(206,'São Paulo','BRA',9968485), +(207,'Rio de Janeiro','BRA',5598953), +(208,'Salvador','BRA',2302832), +(209,'Belo Horizonte','BRA',2139125), +(210,'Fortaleza','BRA',2097757), +(211,'Brasília','BRA',1969868), +(212,'Curitiba','BRA',1584232), +(213,'Recife','BRA',1378087), +(214,'Porto Alegre','BRA',1314032), +(215,'Manaus','BRA',1255049), +(216,'Belém','BRA',1186926), +(217,'Guarulhos','BRA',1095874), +(218,'Goiânia','BRA',1056330), +(219,'Campinas','BRA',950043), +(220,'São Gonçalo','BRA',869254), +(221,'Nova Iguaçu','BRA',862225), +(222,'São Luís','BRA',837588), +(223,'Maceió','BRA',786288), +(224,'Duque de Caxias','BRA',746758), +(225,'São Bernardo do Campo','BRA',723132), +(226,'Teresina','BRA',691942), +(227,'Natal','BRA',688955), +(228,'Osasco','BRA',659604), +(229,'Campo Grande','BRA',649593), +(230,'Santo André','BRA',630073), +(231,'João Pessoa','BRA',584029), +(232,'Jaboatão dos Guararapes','BRA',558680), +(233,'Contagem','BRA',520801), +(234,'São José dos Campos','BRA',515553), +(235,'Uberlândia','BRA',487222), +(236,'Feira de Santana','BRA',479992), +(237,'Ribeirão Preto','BRA',473276), +(238,'Sorocaba','BRA',466823), +(239,'Niterói','BRA',459884), +(240,'Cuiabá','BRA',453813), +(241,'Juiz de Fora','BRA',450288), +(242,'Aracaju','BRA',445555), +(243,'São João de Meriti','BRA',440052), +(244,'Londrina','BRA',432257), +(245,'Joinville','BRA',428011), +(246,'Belford Roxo','BRA',425194), +(247,'Santos','BRA',408748), +(248,'Ananindeua','BRA',400940), +(249,'Campos dos Goytacazes','BRA',398418), +(250,'Mauá','BRA',375055), +(251,'Carapicuíba','BRA',357552), +(252,'Olinda','BRA',354732), +(253,'Campina Grande','BRA',352497), +(254,'São José do Rio Preto','BRA',351944), +(255,'Caxias do Sul','BRA',349581), +(256,'Moji das Cruzes','BRA',339194), +(257,'Diadema','BRA',335078), +(258,'Aparecida de Goiânia','BRA',324662), +(259,'Piracicaba','BRA',319104), +(260,'Cariacica','BRA',319033), +(261,'Vila Velha','BRA',318758), +(262,'Pelotas','BRA',315415), +(263,'Bauru','BRA',313670), +(264,'Porto Velho','BRA',309750), +(265,'Serra','BRA',302666), +(266,'Betim','BRA',302108), +(267,'Jundíaí','BRA',296127), +(268,'Canoas','BRA',294125), +(269,'Franca','BRA',290139), +(270,'São Vicente','BRA',286848), +(271,'Maringá','BRA',286461), +(272,'Montes Claros','BRA',286058), +(273,'Anápolis','BRA',282197), +(274,'Florianópolis','BRA',281928), +(275,'Petrópolis','BRA',279183), +(276,'Itaquaquecetuba','BRA',270874), +(277,'Vitória','BRA',270626), +(278,'Ponta Grossa','BRA',268013), +(279,'Rio Branco','BRA',259537), +(280,'Foz do Iguaçu','BRA',259425), +(281,'Macapá','BRA',256033), +(282,'Ilhéus','BRA',254970), +(283,'Vitória da Conquista','BRA',253587), +(284,'Uberaba','BRA',249225), +(285,'Paulista','BRA',248473), +(286,'Limeira','BRA',245497), +(287,'Blumenau','BRA',244379), +(288,'Caruaru','BRA',244247), +(289,'Santarém','BRA',241771), +(290,'Volta Redonda','BRA',240315), +(291,'Novo Hamburgo','BRA',239940), +(292,'Caucaia','BRA',238738), +(293,'Santa Maria','BRA',238473), +(294,'Cascavel','BRA',237510), +(295,'Guarujá','BRA',237206), +(296,'Ribeirão das Neves','BRA',232685), +(297,'Governador Valadares','BRA',231724), +(298,'Taubaté','BRA',229130), +(299,'Imperatriz','BRA',224564), +(300,'Gravataí','BRA',223011), +(301,'Embu','BRA',222223), +(302,'Mossoró','BRA',214901), +(303,'Várzea Grande','BRA',214435), +(304,'Petrolina','BRA',210540), +(305,'Barueri','BRA',208426), +(306,'Viamão','BRA',207557), +(307,'Ipatinga','BRA',206338), +(308,'Juazeiro','BRA',201073), +(309,'Juazeiro do Norte','BRA',199636), +(310,'Taboão da Serra','BRA',197550), +(311,'São José dos Pinhais','BRA',196884), +(312,'Magé','BRA',196147), +(313,'Suzano','BRA',195434), +(314,'São Leopoldo','BRA',189258), +(315,'Marília','BRA',188691), +(316,'São Carlos','BRA',187122), +(317,'Sumaré','BRA',186205), +(318,'Presidente Prudente','BRA',185340), +(319,'Divinópolis','BRA',185047), +(320,'Sete Lagoas','BRA',182984), +(321,'Rio Grande','BRA',182222), +(322,'Itabuna','BRA',182148), +(323,'Jequié','BRA',179128), +(324,'Arapiraca','BRA',178988), +(325,'Colombo','BRA',177764), +(326,'Americana','BRA',177409), +(327,'Alvorada','BRA',175574), +(328,'Araraquara','BRA',174381), +(329,'Itaboraí','BRA',173977), +(330,'Santa Bárbara d´Oeste','BRA',171657), +(331,'Nova Friburgo','BRA',170697), +(332,'Jacareí','BRA',170356), +(333,'Araçatuba','BRA',169303), +(334,'Barra Mansa','BRA',168953), +(335,'Praia Grande','BRA',168434), +(336,'Marabá','BRA',167795), +(337,'Criciúma','BRA',167661), +(338,'Boa Vista','BRA',167185), +(339,'Passo Fundo','BRA',166343), +(340,'Dourados','BRA',164716), +(341,'Santa Luzia','BRA',164704), +(342,'Rio Claro','BRA',163551), +(343,'Maracanaú','BRA',162022), +(344,'Guarapuava','BRA',160510), +(345,'Rondonópolis','BRA',155115), +(346,'São José','BRA',155105), +(347,'Cachoeiro de Itapemirim','BRA',155024), +(348,'Nilópolis','BRA',153383), +(349,'Itapevi','BRA',150664), +(350,'Cabo de Santo Agostinho','BRA',149964), +(351,'Camaçari','BRA',149146), +(352,'Sobral','BRA',146005), +(353,'Itajaí','BRA',145197), +(354,'Chapecó','BRA',144158), +(355,'Cotia','BRA',140042), +(356,'Lages','BRA',139570), +(357,'Ferraz de Vasconcelos','BRA',139283), +(358,'Indaiatuba','BRA',135968), +(359,'Hortolândia','BRA',135755), +(360,'Caxias','BRA',133980), +(361,'São Caetano do Sul','BRA',133321), +(362,'Itu','BRA',132736), +(363,'Nossa Senhora do Socorro','BRA',131351), +(364,'Parnaíba','BRA',129756), +(365,'Poços de Caldas','BRA',129683), +(366,'Teresópolis','BRA',128079), +(367,'Barreiras','BRA',127801), +(368,'Castanhal','BRA',127634), +(369,'Alagoinhas','BRA',126820), +(370,'Itapecerica da Serra','BRA',126672), +(371,'Uruguaiana','BRA',126305), +(372,'Paranaguá','BRA',126076), +(373,'Ibirité','BRA',125982), +(374,'Timon','BRA',125812), +(375,'Luziânia','BRA',125597), +(376,'Macaé','BRA',125597), +(377,'Teófilo Otoni','BRA',124489), +(378,'Moji-Guaçu','BRA',123782), +(379,'Palmas','BRA',121919), +(380,'Pindamonhangaba','BRA',121904), +(381,'Francisco Morato','BRA',121197), +(382,'Bagé','BRA',120793), +(383,'Sapucaia do Sul','BRA',120217), +(384,'Cabo Frio','BRA',119503), +(385,'Itapetininga','BRA',119391), +(386,'Patos de Minas','BRA',119262), +(387,'Camaragibe','BRA',118968), +(388,'Bragança Paulista','BRA',116929), +(389,'Queimados','BRA',115020), +(390,'Araguaína','BRA',114948), +(391,'Garanhuns','BRA',114603), +(392,'Vitória de Santo Antão','BRA',113595), +(393,'Santa Rita','BRA',113135), +(394,'Barbacena','BRA',113079), +(395,'Abaetetuba','BRA',111258), +(396,'Jaú','BRA',109965), +(397,'Lauro de Freitas','BRA',109236), +(398,'Franco da Rocha','BRA',108964), +(399,'Teixeira de Freitas','BRA',108441), +(400,'Varginha','BRA',108314); +INSERT INTO City VALUES +(401,'Ribeirão Pires','BRA',108121), +(402,'Sabará','BRA',107781), +(403,'Catanduva','BRA',107761), +(404,'Rio Verde','BRA',107755), +(405,'Botucatu','BRA',107663), +(406,'Colatina','BRA',107354), +(407,'Santa Cruz do Sul','BRA',106734), +(408,'Linhares','BRA',106278), +(409,'Apucarana','BRA',105114), +(410,'Barretos','BRA',104156), +(411,'Guaratinguetá','BRA',103433), +(412,'Cachoeirinha','BRA',103240), +(413,'Codó','BRA',103153), +(414,'Jaraguá do Sul','BRA',102580), +(415,'Cubatão','BRA',102372), +(416,'Itabira','BRA',102217), +(417,'Itaituba','BRA',101320), +(418,'Araras','BRA',101046), +(419,'Resende','BRA',100627), +(420,'Atibaia','BRA',100356), +(421,'Pouso Alegre','BRA',100028), +(422,'Toledo','BRA',99387), +(423,'Crato','BRA',98965), +(424,'Passos','BRA',98570), +(425,'Araguari','BRA',98399), +(426,'São José de Ribamar','BRA',98318), +(427,'Pinhais','BRA',98198), +(428,'Sertãozinho','BRA',98140), +(429,'Conselheiro Lafaiete','BRA',97507), +(430,'Paulo Afonso','BRA',97291), +(431,'Angra dos Reis','BRA',96864), +(432,'Eunápolis','BRA',96610), +(433,'Salto','BRA',96348), +(434,'Ourinhos','BRA',96291), +(435,'Parnamirim','BRA',96210), +(436,'Jacobina','BRA',96131), +(437,'Coronel Fabriciano','BRA',95933), +(438,'Birigui','BRA',94685), +(439,'Tatuí','BRA',93897), +(440,'Ji-Paraná','BRA',93346), +(441,'Bacabal','BRA',93121), +(442,'Cametá','BRA',92779), +(443,'Guaíba','BRA',92224), +(444,'São Lourenço da Mata','BRA',91999), +(445,'Santana do Livramento','BRA',91779), +(446,'Votorantim','BRA',91777), +(447,'Campo Largo','BRA',91203), +(448,'Patos','BRA',90519), +(449,'Ituiutaba','BRA',90507), +(450,'Corumbá','BRA',90111), +(451,'Palhoça','BRA',89465), +(452,'Barra do Piraí','BRA',89388), +(453,'Bento Gonçalves','BRA',89254), +(454,'Poá','BRA',89236), +(455,'Águas Lindas de Goiás','BRA',89200), +(456,'London','GBR',7285000), +(457,'Birmingham','GBR',1013000), +(458,'Glasgow','GBR',619680), +(459,'Liverpool','GBR',461000), +(460,'Edinburgh','GBR',450180), +(461,'Sheffield','GBR',431607), +(462,'Manchester','GBR',430000), +(463,'Leeds','GBR',424194), +(464,'Bristol','GBR',402000), +(465,'Cardiff','GBR',321000), +(466,'Coventry','GBR',304000), +(467,'Leicester','GBR',294000), +(468,'Bradford','GBR',289376), +(469,'Belfast','GBR',287500), +(470,'Nottingham','GBR',287000), +(471,'Kingston upon Hull','GBR',262000), +(472,'Plymouth','GBR',253000), +(473,'Stoke-on-Trent','GBR',252000), +(474,'Wolverhampton','GBR',242000), +(475,'Derby','GBR',236000), +(476,'Swansea','GBR',230000), +(477,'Southampton','GBR',216000), +(478,'Aberdeen','GBR',213070), +(479,'Northampton','GBR',196000), +(480,'Dudley','GBR',192171), +(481,'Portsmouth','GBR',190000), +(482,'Newcastle upon Tyne','GBR',189150), +(483,'Sunderland','GBR',183310), +(484,'Luton','GBR',183000), +(485,'Swindon','GBR',180000), +(486,'Southend-on-Sea','GBR',176000), +(487,'Walsall','GBR',174739), +(488,'Bournemouth','GBR',162000), +(489,'Peterborough','GBR',156000), +(490,'Brighton','GBR',156124), +(491,'Blackpool','GBR',151000), +(492,'Dundee','GBR',146690), +(493,'West Bromwich','GBR',146386), +(494,'Reading','GBR',148000), +(495,'Oldbury/Smethwick (Warley)','GBR',145542), +(496,'Middlesbrough','GBR',145000), +(497,'Huddersfield','GBR',143726), +(498,'Oxford','GBR',144000), +(499,'Poole','GBR',141000), +(500,'Bolton','GBR',139020), +(501,'Blackburn','GBR',140000), +(502,'Newport','GBR',139000), +(503,'Preston','GBR',135000), +(504,'Stockport','GBR',132813), +(505,'Norwich','GBR',124000), +(506,'Rotherham','GBR',121380), +(507,'Cambridge','GBR',121000), +(508,'Watford','GBR',113080), +(509,'Ipswich','GBR',114000), +(510,'Slough','GBR',112000), +(511,'Exeter','GBR',111000), +(512,'Cheltenham','GBR',106000), +(513,'Gloucester','GBR',107000), +(514,'Saint Helens','GBR',106293), +(515,'Sutton Coldfield','GBR',106001), +(516,'York','GBR',104425), +(517,'Oldham','GBR',103931), +(518,'Basildon','GBR',100924), +(519,'Worthing','GBR',100000), +(520,'Chelmsford','GBR',97451), +(521,'Colchester','GBR',96063), +(522,'Crawley','GBR',97000), +(523,'Gillingham','GBR',92000), +(524,'Solihull','GBR',94531), +(525,'Rochdale','GBR',94313), +(526,'Birkenhead','GBR',93087), +(527,'Worcester','GBR',95000), +(528,'Hartlepool','GBR',92000), +(529,'Halifax','GBR',91069), +(530,'Woking/Byfleet','GBR',92000), +(531,'Southport','GBR',90959), +(532,'Maidstone','GBR',90878), +(533,'Eastbourne','GBR',90000), +(534,'Grimsby','GBR',89000), +(535,'Saint Helier','GBR',27523), +(536,'Douglas','GBR',23487), +(537,'Road Town','VGB',8000), +(538,'Bandar Seri Begawan','BRN',21484), +(539,'Sofija','BGR',1122302), +(540,'Plovdiv','BGR',342584), +(541,'Varna','BGR',299801), +(542,'Burgas','BGR',195255), +(543,'Ruse','BGR',166467), +(544,'Stara Zagora','BGR',147939), +(545,'Pleven','BGR',121952), +(546,'Sliven','BGR',105530), +(547,'Dobric','BGR',100399), +(548,'Šumen','BGR',94686), +(549,'Ouagadougou','BFA',824000), +(550,'Bobo-Dioulasso','BFA',300000), +(551,'Koudougou','BFA',105000), +(552,'Bujumbura','BDI',300000), +(553,'George Town','CYM',19600), +(554,'Santiago de Chile','CHL',4703954), +(555,'Puente Alto','CHL',386236), +(556,'Viña del Mar','CHL',312493), +(557,'Valparaíso','CHL',293800), +(558,'Talcahuano','CHL',277752), +(559,'Antofagasta','CHL',251429), +(560,'San Bernardo','CHL',241910), +(561,'Temuco','CHL',233041), +(562,'Concepción','CHL',217664), +(563,'Rancagua','CHL',212977), +(564,'Arica','CHL',189036), +(565,'Talca','CHL',187557), +(566,'Chillán','CHL',178182), +(567,'Iquique','CHL',177892), +(568,'Los Angeles','CHL',158215), +(569,'Puerto Montt','CHL',152194), +(570,'Coquimbo','CHL',143353), +(571,'Osorno','CHL',141468), +(572,'La Serena','CHL',137409), +(573,'Calama','CHL',137265), +(574,'Valdivia','CHL',133106), +(575,'Punta Arenas','CHL',125631), +(576,'Copiapó','CHL',120128), +(577,'Quilpué','CHL',118857), +(578,'Curicó','CHL',115766), +(579,'Ovalle','CHL',94854), +(580,'Coronel','CHL',93061), +(581,'San Pedro de la Paz','CHL',91684), +(582,'Melipilla','CHL',91056), +(583,'Avarua','COK',11900), +(584,'San José','CRI',339131), +(585,'Djibouti','DJI',383000), +(586,'Roseau','DMA',16243), +(587,'Santo Domingo de Guzmán','DOM',1609966), +(588,'Santiago de los Caballeros','DOM',365463), +(589,'La Romana','DOM',140204), +(590,'San Pedro de Macorís','DOM',124735), +(591,'San Francisco de Macorís','DOM',108485), +(592,'San Felipe de Puerto Plata','DOM',89423), +(593,'Guayaquil','ECU',2070040), +(594,'Quito','ECU',1573458), +(595,'Cuenca','ECU',270353), +(596,'Machala','ECU',210368), +(597,'Santo Domingo de los Colorados','ECU',202111), +(598,'Portoviejo','ECU',176413), +(599,'Ambato','ECU',169612), +(600,'Manta','ECU',164739); +INSERT INTO City VALUES +(601,'Duran [Eloy Alfaro]','ECU',152514), +(602,'Ibarra','ECU',130643), +(603,'Quevedo','ECU',129631), +(604,'Milagro','ECU',124177), +(605,'Loja','ECU',123875), +(606,'Ríobamba','ECU',123163), +(607,'Esmeraldas','ECU',123045), +(608,'Cairo','EGY',6789479), +(609,'Alexandria','EGY',3328196), +(610,'Giza','EGY',2221868), +(611,'Shubra al-Khayma','EGY',870716), +(612,'Port Said','EGY',469533), +(613,'Suez','EGY',417610), +(614,'al-Mahallat al-Kubra','EGY',395402), +(615,'Tanta','EGY',371010), +(616,'al-Mansura','EGY',369621), +(617,'Luxor','EGY',360503), +(618,'Asyut','EGY',343498), +(619,'Bahtim','EGY',275807), +(620,'Zagazig','EGY',267351), +(621,'al-Faiyum','EGY',260964), +(622,'Ismailia','EGY',254477), +(623,'Kafr al-Dawwar','EGY',231978), +(624,'Assuan','EGY',219017), +(625,'Damanhur','EGY',212203), +(626,'al-Minya','EGY',201360), +(627,'Bani Suwayf','EGY',172032), +(628,'Qina','EGY',171275), +(629,'Sawhaj','EGY',170125), +(630,'Shibin al-Kawm','EGY',159909), +(631,'Bulaq al-Dakrur','EGY',148787), +(632,'Banha','EGY',145792), +(633,'Warraq al-Arab','EGY',127108), +(634,'Kafr al-Shaykh','EGY',124819), +(635,'Mallawi','EGY',119283), +(636,'Bilbays','EGY',113608), +(637,'Mit Ghamr','EGY',101801), +(638,'al-Arish','EGY',100447), +(639,'Talkha','EGY',97700), +(640,'Qalyub','EGY',97200), +(641,'Jirja','EGY',95400), +(642,'Idfu','EGY',94200), +(643,'al-Hawamidiya','EGY',91700), +(644,'Disuq','EGY',91300), +(645,'San Salvador','SLV',415346), +(646,'Santa Ana','SLV',139389), +(647,'Mejicanos','SLV',138800), +(648,'Soyapango','SLV',129800), +(649,'San Miguel','SLV',127696), +(650,'Nueva San Salvador','SLV',98400), +(651,'Apopa','SLV',88800), +(652,'Asmara','ERI',431000), +(653,'Madrid','ESP',2879052), +(654,'Barcelona','ESP',1503451), +(655,'Valencia','ESP',739412), +(656,'Sevilla','ESP',701927), +(657,'Zaragoza','ESP',603367), +(658,'Málaga','ESP',530553), +(659,'Bilbao','ESP',357589), +(660,'Las Palmas de Gran Canaria','ESP',354757), +(661,'Murcia','ESP',353504), +(662,'Palma de Mallorca','ESP',326993), +(663,'Valladolid','ESP',319998), +(664,'Córdoba','ESP',311708), +(665,'Vigo','ESP',283670), +(666,'Alicante [Alacant]','ESP',272432), +(667,'Gijón','ESP',267980), +(668,'L´Hospitalet de Llobregat','ESP',247986), +(669,'Granada','ESP',244767), +(670,'A Coruña (La Coruña)','ESP',243402), +(671,'Vitoria-Gasteiz','ESP',217154), +(672,'Santa Cruz de Tenerife','ESP',213050), +(673,'Badalona','ESP',209635), +(674,'Oviedo','ESP',200453), +(675,'Móstoles','ESP',195351), +(676,'Elche [Elx]','ESP',193174), +(677,'Sabadell','ESP',184859), +(678,'Santander','ESP',184165), +(679,'Jerez de la Frontera','ESP',182660), +(680,'Pamplona [Iruña]','ESP',180483), +(681,'Donostia-San Sebastián','ESP',179208), +(682,'Cartagena','ESP',177709), +(683,'Leganés','ESP',173163), +(684,'Fuenlabrada','ESP',171173), +(685,'Almería','ESP',169027), +(686,'Terrassa','ESP',168695), +(687,'Alcalá de Henares','ESP',164463), +(688,'Burgos','ESP',162802), +(689,'Salamanca','ESP',158720), +(690,'Albacete','ESP',147527), +(691,'Getafe','ESP',145371), +(692,'Cádiz','ESP',142449), +(693,'Alcorcón','ESP',142048), +(694,'Huelva','ESP',140583), +(695,'León','ESP',139809), +(696,'Castellón de la Plana [Castell','ESP',139712), +(697,'Badajoz','ESP',136613), +(698,'[San Cristóbal de] la Laguna','ESP',127945), +(699,'Logroño','ESP',127093), +(700,'Santa Coloma de Gramenet','ESP',120802), +(701,'Tarragona','ESP',113016), +(702,'Lleida (Lérida)','ESP',112207), +(703,'Jaén','ESP',109247), +(704,'Ourense (Orense)','ESP',109120), +(705,'Mataró','ESP',104095), +(706,'Algeciras','ESP',103106), +(707,'Marbella','ESP',101144), +(708,'Barakaldo','ESP',98212), +(709,'Dos Hermanas','ESP',94591), +(710,'Santiago de Compostela','ESP',93745), +(711,'Torrejón de Ardoz','ESP',92262), +(712,'Cape Town','ZAF',2352121), +(713,'Soweto','ZAF',904165), +(714,'Johannesburg','ZAF',756653), +(715,'Port Elizabeth','ZAF',752319), +(716,'Pretoria','ZAF',658630), +(717,'Inanda','ZAF',634065), +(718,'Durban','ZAF',566120), +(719,'Vanderbijlpark','ZAF',468931), +(720,'Kempton Park','ZAF',442633), +(721,'Alberton','ZAF',410102), +(722,'Pinetown','ZAF',378810), +(723,'Pietermaritzburg','ZAF',370190), +(724,'Benoni','ZAF',365467), +(725,'Randburg','ZAF',341288), +(726,'Umlazi','ZAF',339233), +(727,'Bloemfontein','ZAF',334341), +(728,'Vereeniging','ZAF',328535), +(729,'Wonderboom','ZAF',283289), +(730,'Roodepoort','ZAF',279340), +(731,'Boksburg','ZAF',262648), +(732,'Klerksdorp','ZAF',261911), +(733,'Soshanguve','ZAF',242727), +(734,'Newcastle','ZAF',222993), +(735,'East London','ZAF',221047), +(736,'Welkom','ZAF',203296), +(737,'Kimberley','ZAF',197254), +(738,'Uitenhage','ZAF',192120), +(739,'Chatsworth','ZAF',189885), +(740,'Mdantsane','ZAF',182639), +(741,'Krugersdorp','ZAF',181503), +(742,'Botshabelo','ZAF',177971), +(743,'Brakpan','ZAF',171363), +(744,'Witbank','ZAF',167183), +(745,'Oberholzer','ZAF',164367), +(746,'Germiston','ZAF',164252), +(747,'Springs','ZAF',162072), +(748,'Westonaria','ZAF',159632), +(749,'Randfontein','ZAF',120838), +(750,'Paarl','ZAF',105768), +(751,'Potchefstroom','ZAF',101817), +(752,'Rustenburg','ZAF',97008), +(753,'Nigel','ZAF',96734), +(754,'George','ZAF',93818), +(755,'Ladysmith','ZAF',89292), +(756,'Addis Abeba','ETH',2495000), +(757,'Dire Dawa','ETH',164851), +(758,'Nazret','ETH',127842), +(759,'Gonder','ETH',112249), +(760,'Dese','ETH',97314), +(761,'Mekele','ETH',96938), +(762,'Bahir Dar','ETH',96140), +(763,'Stanley','FLK',1636), +(764,'Suva','FJI',77366), +(765,'Quezon','PHL',2173831), +(766,'Manila','PHL',1581082), +(767,'Kalookan','PHL',1177604), +(768,'Davao','PHL',1147116), +(769,'Cebu','PHL',718821), +(770,'Zamboanga','PHL',601794), +(771,'Pasig','PHL',505058), +(772,'Valenzuela','PHL',485433), +(773,'Las Piñas','PHL',472780), +(774,'Antipolo','PHL',470866), +(775,'Taguig','PHL',467375), +(776,'Cagayan de Oro','PHL',461877), +(777,'Parañaque','PHL',449811), +(778,'Makati','PHL',444867), +(779,'Bacolod','PHL',429076), +(780,'General Santos','PHL',411822), +(781,'Marikina','PHL',391170), +(782,'Dasmariñas','PHL',379520), +(783,'Muntinlupa','PHL',379310), +(784,'Iloilo','PHL',365820), +(785,'Pasay','PHL',354908), +(786,'Malabon','PHL',338855), +(787,'San José del Monte','PHL',315807), +(788,'Bacoor','PHL',305699), +(789,'Iligan','PHL',285061), +(790,'Calamba','PHL',281146), +(791,'Mandaluyong','PHL',278474), +(792,'Butuan','PHL',267279), +(793,'Angeles','PHL',263971), +(794,'Tarlac','PHL',262481), +(795,'Mandaue','PHL',259728), +(796,'Baguio','PHL',252386), +(797,'Batangas','PHL',247588), +(798,'Cainta','PHL',242511), +(799,'San Pedro','PHL',231403), + (800,'Navotas','PHL',230403); +INSERT INTO City VALUES +(801,'Cabanatuan','PHL',222859), +(802,'San Fernando','PHL',221857), +(803,'Lipa','PHL',218447), +(804,'Lapu-Lapu','PHL',217019), +(805,'San Pablo','PHL',207927), +(806,'Biñan','PHL',201186), +(807,'Taytay','PHL',198183), +(808,'Lucena','PHL',196075), +(809,'Imus','PHL',195482), +(810,'Olongapo','PHL',194260), +(811,'Binangonan','PHL',187691), +(812,'Santa Rosa','PHL',185633), +(813,'Tagum','PHL',179531), +(814,'Tacloban','PHL',178639), +(815,'Malolos','PHL',175291), +(816,'Mabalacat','PHL',171045), +(817,'Cotabato','PHL',163849), +(818,'Meycauayan','PHL',163037), +(819,'Puerto Princesa','PHL',161912), +(820,'Legazpi','PHL',157010), +(821,'Silang','PHL',156137), +(822,'Ormoc','PHL',154297), +(823,'San Carlos','PHL',154264), +(824,'Kabankalan','PHL',149769), +(825,'Talisay','PHL',148110), +(826,'Valencia','PHL',147924), +(827,'Calbayog','PHL',147187), +(828,'Santa Maria','PHL',144282), +(829,'Pagadian','PHL',142515), +(830,'Cadiz','PHL',141954), +(831,'Bago','PHL',141721), +(832,'Toledo','PHL',141174), +(833,'Naga','PHL',137810), +(834,'San Mateo','PHL',135603), +(835,'Panabo','PHL',133950), +(836,'Koronadal','PHL',133786), +(837,'Marawi','PHL',131090), +(838,'Dagupan','PHL',130328), +(839,'Sagay','PHL',129765), +(840,'Roxas','PHL',126352), +(841,'Lubao','PHL',125699), +(842,'Digos','PHL',125171), +(843,'San Miguel','PHL',123824), +(844,'Malaybalay','PHL',123672), +(845,'Tuguegarao','PHL',120645), +(846,'Ilagan','PHL',119990), +(847,'Baliuag','PHL',119675), +(848,'Surigao','PHL',118534), +(849,'San Carlos','PHL',118259), +(850,'San Juan del Monte','PHL',117680), +(851,'Tanauan','PHL',117539), +(852,'Concepcion','PHL',115171), +(853,'Rodriguez (Montalban)','PHL',115167), +(854,'Sariaya','PHL',114568), +(855,'Malasiqui','PHL',113190), +(856,'General Mariano Alvarez','PHL',112446), +(857,'Urdaneta','PHL',111582), +(858,'Hagonoy','PHL',111425), +(859,'San Jose','PHL',111009), +(860,'Polomolok','PHL',110709), +(861,'Santiago','PHL',110531), +(862,'Tanza','PHL',110517), +(863,'Ozamis','PHL',110420), +(864,'Mexico','PHL',109481), +(865,'San Jose','PHL',108254), +(866,'Silay','PHL',107722), +(867,'General Trias','PHL',107691), +(868,'Tabaco','PHL',107166), +(869,'Cabuyao','PHL',106630), +(870,'Calapan','PHL',105910), +(871,'Mati','PHL',105908), +(872,'Midsayap','PHL',105760), +(873,'Cauayan','PHL',103952), +(874,'Gingoog','PHL',102379), +(875,'Dumaguete','PHL',102265), +(876,'San Fernando','PHL',102082), +(877,'Arayat','PHL',101792), +(878,'Bayawan (Tulong)','PHL',101391), +(879,'Kidapawan','PHL',101205), +(880,'Daraga (Locsin)','PHL',101031), +(881,'Marilao','PHL',101017), +(882,'Malita','PHL',100000), +(883,'Dipolog','PHL',99862), +(884,'Cavite','PHL',99367), +(885,'Danao','PHL',98781), +(886,'Bislig','PHL',97860), +(887,'Talavera','PHL',97329), +(888,'Guagua','PHL',96858), +(889,'Bayambang','PHL',96609), +(890,'Nasugbu','PHL',96113), +(891,'Baybay','PHL',95630), +(892,'Capas','PHL',95219), +(893,'Sultan Kudarat','PHL',94861), +(894,'Laoag','PHL',94466), +(895,'Bayugan','PHL',93623), +(896,'Malungon','PHL',93232), +(897,'Santa Cruz','PHL',92694), +(898,'Sorsogon','PHL',92512), +(899,'Candelaria','PHL',92429), +(900,'Ligao','PHL',90603), +(901,'Tórshavn','FRO',14542), +(902,'Libreville','GAB',419000), +(903,'Serekunda','GMB',102600), +(904,'Banjul','GMB',42326), +(905,'Tbilisi','GEO',1235200), +(906,'Kutaisi','GEO',240900), +(907,'Rustavi','GEO',155400), +(908,'Batumi','GEO',137700), +(909,'Sohumi','GEO',111700), +(910,'Accra','GHA',1070000), +(911,'Kumasi','GHA',385192), +(912,'Tamale','GHA',151069), +(913,'Tema','GHA',109975), +(914,'Sekondi-Takoradi','GHA',103653), +(915,'Gibraltar','GIB',27025), +(916,'Saint George´s','GRD',4621), +(917,'Nuuk','GRL',13445), +(918,'Les Abymes','GLP',62947), +(919,'Basse-Terre','GLP',12433), +(920,'Tamuning','GUM',9500), +(921,'Agaña','GUM',1139), +(922,'Ciudad de Guatemala','GTM',823301), +(923,'Mixco','GTM',209791), +(924,'Villa Nueva','GTM',101295), +(925,'Quetzaltenango','GTM',90801), +(926,'Conakry','GIN',1090610), +(927,'Bissau','GNB',241000), +(928,'Georgetown','GUY',254000), +(929,'Port-au-Prince','HTI',884472), +(930,'Carrefour','HTI',290204), +(931,'Delmas','HTI',240429), +(932,'Le-Cap-Haïtien','HTI',102233), +(933,'Tegucigalpa','HND',813900), +(934,'San Pedro Sula','HND',383900), +(935,'La Ceiba','HND',89200), +(936,'Kowloon and New Kowloon','HKG',1987996), +(937,'Victoria','HKG',1312637), +(938,'Longyearbyen','SJM',1438), +(939,'Jakarta','IDN',9604900), +(940,'Surabaya','IDN',2663820), +(941,'Bandung','IDN',2429000), +(942,'Medan','IDN',1843919), +(943,'Palembang','IDN',1222764), +(944,'Tangerang','IDN',1198300), +(945,'Semarang','IDN',1104405), +(946,'Ujung Pandang','IDN',1060257), +(947,'Malang','IDN',716862), +(948,'Bandar Lampung','IDN',680332), +(949,'Bekasi','IDN',644300), +(950,'Padang','IDN',534474), +(951,'Surakarta','IDN',518600), +(952,'Banjarmasin','IDN',482931), +(953,'Pekan Baru','IDN',438638), +(954,'Denpasar','IDN',435000), +(955,'Yogyakarta','IDN',418944), +(956,'Pontianak','IDN',409632), +(957,'Samarinda','IDN',399175), +(958,'Jambi','IDN',385201), +(959,'Depok','IDN',365200), +(960,'Cimahi','IDN',344600), +(961,'Balikpapan','IDN',338752), +(962,'Manado','IDN',332288), +(963,'Mataram','IDN',306600), +(964,'Pekalongan','IDN',301504), +(965,'Tegal','IDN',289744), +(966,'Bogor','IDN',285114), +(967,'Ciputat','IDN',270800), +(968,'Pondokgede','IDN',263200), +(969,'Cirebon','IDN',254406), +(970,'Kediri','IDN',253760), +(971,'Ambon','IDN',249312), +(972,'Jember','IDN',218500), +(973,'Cilacap','IDN',206900), +(974,'Cimanggis','IDN',205100), +(975,'Pematang Siantar','IDN',203056), +(976,'Purwokerto','IDN',202500), +(977,'Ciomas','IDN',187400), +(978,'Tasikmalaya','IDN',179800), +(979,'Madiun','IDN',171532), +(980,'Bengkulu','IDN',146439), +(981,'Karawang','IDN',145000), +(982,'Banda Aceh','IDN',143409), +(983,'Palu','IDN',142800), +(984,'Pasuruan','IDN',134019), +(985,'Kupang','IDN',129300), +(986,'Tebing Tinggi','IDN',129300), +(987,'Percut Sei Tuan','IDN',129000), +(988,'Binjai','IDN',127222), +(989,'Sukabumi','IDN',125766), +(990,'Waru','IDN',124300), +(991,'Pangkal Pinang','IDN',124000), +(992,'Magelang','IDN',123800), +(993,'Blitar','IDN',122600), +(994,'Serang','IDN',122400), +(995,'Probolinggo','IDN',120770), +(996,'Cilegon','IDN',117000), +(997,'Cianjur','IDN',114300), +(998,'Ciparay','IDN',111500), +(999,'Lhokseumawe','IDN',109600), +(1000,'Taman','IDN',107000); +INSERT INTO City VALUES +(1001,'Depok','IDN',106800), +(1002,'Citeureup','IDN',105100), +(1003,'Pemalang','IDN',103500), +(1004,'Klaten','IDN',103300), +(1005,'Salatiga','IDN',103000), +(1006,'Cibinong','IDN',101300), +(1007,'Palangka Raya','IDN',99693), +(1008,'Mojokerto','IDN',96626), +(1009,'Purwakarta','IDN',95900), +(1010,'Garut','IDN',95800), +(1011,'Kudus','IDN',95300), +(1012,'Kendari','IDN',94800), +(1013,'Jaya Pura','IDN',94700), +(1014,'Gorontalo','IDN',94058), +(1015,'Majalaya','IDN',93200), +(1016,'Pondok Aren','IDN',92700), +(1017,'Jombang','IDN',92600), +(1018,'Sunggal','IDN',92300), +(1019,'Batam','IDN',91871), +(1020,'Padang Sidempuan','IDN',91200), +(1021,'Sawangan','IDN',91100), +(1022,'Banyuwangi','IDN',89900), +(1023,'Tanjung Pinang','IDN',89900), +(1024,'Mumbai (Bombay)','IND',10500000), +(1025,'Delhi','IND',7206704), +(1026,'Calcutta [Kolkata]','IND',4399819), +(1027,'Chennai (Madras)','IND',3841396), +(1028,'Hyderabad','IND',2964638), +(1029,'Ahmedabad','IND',2876710), +(1030,'Bangalore','IND',2660088), +(1031,'Kanpur','IND',1874409), +(1032,'Nagpur','IND',1624752), +(1033,'Lucknow','IND',1619115), +(1034,'Pune','IND',1566651), +(1035,'Surat','IND',1498817), +(1036,'Jaipur','IND',1458483), +(1037,'Indore','IND',1091674), +(1038,'Bhopal','IND',1062771), +(1039,'Ludhiana','IND',1042740), +(1040,'Vadodara (Baroda)','IND',1031346), +(1041,'Kalyan','IND',1014557), +(1042,'Madurai','IND',977856), +(1043,'Haora (Howrah)','IND',950435), +(1044,'Varanasi (Benares)','IND',929270), +(1045,'Patna','IND',917243), +(1046,'Srinagar','IND',892506), +(1047,'Agra','IND',891790), +(1048,'Coimbatore','IND',816321), +(1049,'Thane (Thana)','IND',803389), +(1050,'Allahabad','IND',792858), +(1051,'Meerut','IND',753778), +(1052,'Vishakhapatnam','IND',752037), +(1053,'Jabalpur','IND',741927), +(1054,'Amritsar','IND',708835), +(1055,'Faridabad','IND',703592), +(1056,'Vijayawada','IND',701827), +(1057,'Gwalior','IND',690765), +(1058,'Jodhpur','IND',666279), +(1059,'Nashik (Nasik)','IND',656925), +(1060,'Hubli-Dharwad','IND',648298), +(1061,'Solapur (Sholapur)','IND',604215), +(1062,'Ranchi','IND',599306), +(1063,'Bareilly','IND',587211), +(1064,'Guwahati (Gauhati)','IND',584342), +(1065,'Shambajinagar (Aurangabad)','IND',573272), +(1066,'Cochin (Kochi)','IND',564589), +(1067,'Rajkot','IND',559407), +(1068,'Kota','IND',537371), +(1069,'Thiruvananthapuram (Trivandrum','IND',524006), +(1070,'Pimpri-Chinchwad','IND',517083), +(1071,'Jalandhar (Jullundur)','IND',509510), +(1072,'Gorakhpur','IND',505566), +(1073,'Chandigarh','IND',504094), +(1074,'Mysore','IND',480692), +(1075,'Aligarh','IND',480520), +(1076,'Guntur','IND',471051), +(1077,'Jamshedpur','IND',460577), +(1078,'Ghaziabad','IND',454156), +(1079,'Warangal','IND',447657), +(1080,'Raipur','IND',438639), +(1081,'Moradabad','IND',429214), +(1082,'Durgapur','IND',425836), +(1083,'Amravati','IND',421576), +(1084,'Calicut (Kozhikode)','IND',419831), +(1085,'Bikaner','IND',416289), +(1086,'Bhubaneswar','IND',411542), +(1087,'Kolhapur','IND',406370), +(1088,'Kataka (Cuttack)','IND',403418), +(1089,'Ajmer','IND',402700), +(1090,'Bhavnagar','IND',402338), +(1091,'Tiruchirapalli','IND',387223), +(1092,'Bhilai','IND',386159), +(1093,'Bhiwandi','IND',379070), +(1094,'Saharanpur','IND',374945), +(1095,'Ulhasnagar','IND',369077), +(1096,'Salem','IND',366712), +(1097,'Ujjain','IND',362266), +(1098,'Malegaon','IND',342595), +(1099,'Jamnagar','IND',341637), +(1100,'Bokaro Steel City','IND',333683), +(1101,'Akola','IND',328034), +(1102,'Belgaum','IND',326399), +(1103,'Rajahmundry','IND',324851), +(1104,'Nellore','IND',316606), +(1105,'Udaipur','IND',308571), +(1106,'New Bombay','IND',307297), +(1107,'Bhatpara','IND',304952), +(1108,'Gulbarga','IND',304099), +(1109,'New Delhi','IND',301297), +(1110,'Jhansi','IND',300850), +(1111,'Gaya','IND',291675), +(1112,'Kakinada','IND',279980), +(1113,'Dhule (Dhulia)','IND',278317), +(1114,'Panihati','IND',275990), +(1115,'Nanded (Nander)','IND',275083), +(1116,'Mangalore','IND',273304), +(1117,'Dehra Dun','IND',270159), +(1118,'Kamarhati','IND',266889), +(1119,'Davangere','IND',266082), +(1120,'Asansol','IND',262188), +(1121,'Bhagalpur','IND',253225), +(1122,'Bellary','IND',245391), +(1123,'Barddhaman (Burdwan)','IND',245079), +(1124,'Rampur','IND',243742), +(1125,'Jalgaon','IND',242193), +(1126,'Muzaffarpur','IND',241107), +(1127,'Nizamabad','IND',241034), +(1128,'Muzaffarnagar','IND',240609), +(1129,'Patiala','IND',238368), +(1130,'Shahjahanpur','IND',237713), +(1131,'Kurnool','IND',236800), +(1132,'Tiruppur (Tirupper)','IND',235661), +(1133,'Rohtak','IND',233400), +(1134,'South Dum Dum','IND',232811), +(1135,'Mathura','IND',226691), +(1136,'Chandrapur','IND',226105), +(1137,'Barahanagar (Baranagar)','IND',224821), +(1138,'Darbhanga','IND',218391), +(1139,'Siliguri (Shiliguri)','IND',216950), +(1140,'Raurkela','IND',215489), +(1141,'Ambattur','IND',215424), +(1142,'Panipat','IND',215218), +(1143,'Firozabad','IND',215128), +(1144,'Ichalkaranji','IND',214950), +(1145,'Jammu','IND',214737), +(1146,'Ramagundam','IND',214384), +(1147,'Eluru','IND',212866), +(1148,'Brahmapur','IND',210418), +(1149,'Alwar','IND',205086), +(1150,'Pondicherry','IND',203065), +(1151,'Thanjavur','IND',202013), +(1152,'Bihar Sharif','IND',201323), +(1153,'Tuticorin','IND',199854), +(1154,'Imphal','IND',198535), +(1155,'Latur','IND',197408), +(1156,'Sagar','IND',195346), +(1157,'Farrukhabad-cum-Fatehgarh','IND',194567), +(1158,'Sangli','IND',193197), +(1159,'Parbhani','IND',190255), +(1160,'Nagar Coil','IND',190084), +(1161,'Bijapur','IND',186939), +(1162,'Kukatpalle','IND',185378), +(1163,'Bally','IND',184474), +(1164,'Bhilwara','IND',183965), +(1165,'Ratlam','IND',183375), +(1166,'Avadi','IND',183215), +(1167,'Dindigul','IND',182477), +(1168,'Ahmadnagar','IND',181339), +(1169,'Bilaspur','IND',179833), +(1170,'Shimoga','IND',179258), +(1171,'Kharagpur','IND',177989), +(1172,'Mira Bhayandar','IND',175372), +(1173,'Vellore','IND',175061), +(1174,'Jalna','IND',174985), +(1175,'Burnpur','IND',174933), +(1176,'Anantapur','IND',174924), +(1177,'Allappuzha (Alleppey)','IND',174666), +(1178,'Tirupati','IND',174369), +(1179,'Karnal','IND',173751), +(1180,'Burhanpur','IND',172710), +(1181,'Hisar (Hissar)','IND',172677), +(1182,'Tiruvottiyur','IND',172562), +(1183,'Mirzapur-cum-Vindhyachal','IND',169336), +(1184,'Secunderabad','IND',167461), +(1185,'Nadiad','IND',167051), +(1186,'Dewas','IND',164364), +(1187,'Murwara (Katni)','IND',163431), +(1188,'Ganganagar','IND',161482), +(1189,'Vizianagaram','IND',160359), +(1190,'Erode','IND',159232), +(1191,'Machilipatnam (Masulipatam)','IND',159110), +(1192,'Bhatinda (Bathinda)','IND',159042), +(1193,'Raichur','IND',157551), +(1194,'Agartala','IND',157358), +(1195,'Arrah (Ara)','IND',157082), +(1196,'Satna','IND',156630), +(1197,'Lalbahadur Nagar','IND',155500), +(1198,'Aizawl','IND',155240), +(1199,'Uluberia','IND',155172), +(1200,'Katihar','IND',154367); +INSERT INTO City VALUES +(1201,'Cuddalore','IND',153086), +(1202,'Hugli-Chinsurah','IND',151806), +(1203,'Dhanbad','IND',151789), +(1204,'Raiganj','IND',151045), +(1205,'Sambhal','IND',150869), +(1206,'Durg','IND',150645), +(1207,'Munger (Monghyr)','IND',150112), +(1208,'Kanchipuram','IND',150100), +(1209,'North Dum Dum','IND',149965), +(1210,'Karimnagar','IND',148583), +(1211,'Bharatpur','IND',148519), +(1212,'Sikar','IND',148272), +(1213,'Hardwar (Haridwar)','IND',147305), +(1214,'Dabgram','IND',147217), +(1215,'Morena','IND',147124), +(1216,'Noida','IND',146514), +(1217,'Hapur','IND',146262), +(1218,'Bhusawal','IND',145143), +(1219,'Khandwa','IND',145133), +(1220,'Yamuna Nagar','IND',144346), +(1221,'Sonipat (Sonepat)','IND',143922), +(1222,'Tenali','IND',143726), +(1223,'Raurkela Civil Township','IND',140408), +(1224,'Kollam (Quilon)','IND',139852), +(1225,'Kumbakonam','IND',139483), +(1226,'Ingraj Bazar (English Bazar)','IND',139204), +(1227,'Timkur','IND',138903), +(1228,'Amroha','IND',137061), +(1229,'Serampore','IND',137028), +(1230,'Chapra','IND',136877), +(1231,'Pali','IND',136842), +(1232,'Maunath Bhanjan','IND',136697), +(1233,'Adoni','IND',136182), +(1234,'Jaunpur','IND',136062), +(1235,'Tirunelveli','IND',135825), +(1236,'Bahraich','IND',135400), +(1237,'Gadag Betigeri','IND',134051), +(1238,'Proddatur','IND',133914), +(1239,'Chittoor','IND',133462), +(1240,'Barrackpur','IND',133265), +(1241,'Bharuch (Broach)','IND',133102), +(1242,'Naihati','IND',132701), +(1243,'Shillong','IND',131719), +(1244,'Sambalpur','IND',131138), +(1245,'Junagadh','IND',130484), +(1246,'Rae Bareli','IND',129904), +(1247,'Rewa','IND',128981), +(1248,'Gurgaon','IND',128608), +(1249,'Khammam','IND',127992), +(1250,'Bulandshahr','IND',127201), +(1251,'Navsari','IND',126089), +(1252,'Malkajgiri','IND',126066), +(1253,'Midnapore (Medinipur)','IND',125498), +(1254,'Miraj','IND',125407), +(1255,'Raj Nandgaon','IND',125371), +(1256,'Alandur','IND',125244), +(1257,'Puri','IND',125199), +(1258,'Navadwip','IND',125037), +(1259,'Sirsa','IND',125000), +(1260,'Korba','IND',124501), +(1261,'Faizabad','IND',124437), +(1262,'Etawah','IND',124072), +(1263,'Pathankot','IND',123930), +(1264,'Gandhinagar','IND',123359), +(1265,'Palghat (Palakkad)','IND',123289), +(1266,'Veraval','IND',123000), +(1267,'Hoshiarpur','IND',122705), +(1268,'Ambala','IND',122596), +(1269,'Sitapur','IND',121842), +(1270,'Bhiwani','IND',121629), +(1271,'Cuddapah','IND',121463), +(1272,'Bhimavaram','IND',121314), +(1273,'Krishnanagar','IND',121110), +(1274,'Chandannagar','IND',120378), +(1275,'Mandya','IND',120265), +(1276,'Dibrugarh','IND',120127), +(1277,'Nandyal','IND',119813), +(1278,'Balurghat','IND',119796), +(1279,'Neyveli','IND',118080), +(1280,'Fatehpur','IND',117675), +(1281,'Mahbubnagar','IND',116833), +(1282,'Budaun','IND',116695), +(1283,'Porbandar','IND',116671), +(1284,'Silchar','IND',115483), +(1285,'Berhampore (Baharampur)','IND',115144), +(1286,'Purnea (Purnia)','IND',114912), +(1287,'Bankura','IND',114876), +(1288,'Rajapalaiyam','IND',114202), +(1289,'Titagarh','IND',114085), +(1290,'Halisahar','IND',114028), +(1291,'Hathras','IND',113285), +(1292,'Bhir (Bid)','IND',112434), +(1293,'Pallavaram','IND',111866), +(1294,'Anand','IND',110266), +(1295,'Mango','IND',110024), +(1296,'Santipur','IND',109956), +(1297,'Bhind','IND',109755), +(1298,'Gondiya','IND',109470), +(1299,'Tiruvannamalai','IND',109196), +(1300,'Yeotmal (Yavatmal)','IND',108578), +(1301,'Kulti-Barakar','IND',108518), +(1302,'Moga','IND',108304), +(1303,'Shivapuri','IND',108277), +(1304,'Bidar','IND',108016), +(1305,'Guntakal','IND',107592), +(1306,'Unnao','IND',107425), +(1307,'Barasat','IND',107365), +(1308,'Tambaram','IND',107187), +(1309,'Abohar','IND',107163), +(1310,'Pilibhit','IND',106605), +(1311,'Valparai','IND',106523), +(1312,'Gonda','IND',106078), +(1313,'Surendranagar','IND',105973), +(1314,'Qutubullapur','IND',105380), +(1315,'Beawar','IND',105363), +(1316,'Hindupur','IND',104651), +(1317,'Gandhidham','IND',104585), +(1318,'Haldwani-cum-Kathgodam','IND',104195), +(1319,'Tellicherry (Thalassery)','IND',103579), +(1320,'Wardha','IND',102985), +(1321,'Rishra','IND',102649), +(1322,'Bhuj','IND',102176), +(1323,'Modinagar','IND',101660), +(1324,'Gudivada','IND',101656), +(1325,'Basirhat','IND',101409), +(1326,'Uttarpara-Kotrung','IND',100867), +(1327,'Ongole','IND',100836), +(1328,'North Barrackpur','IND',100513), +(1329,'Guna','IND',100490), +(1330,'Haldia','IND',100347), +(1331,'Habra','IND',100223), +(1332,'Kanchrapara','IND',100194), +(1333,'Tonk','IND',100079), +(1334,'Champdani','IND',98818), +(1335,'Orai','IND',98640), +(1336,'Pudukkottai','IND',98619), +(1337,'Sasaram','IND',98220), +(1338,'Hazaribag','IND',97712), +(1339,'Palayankottai','IND',97662), +(1340,'Banda','IND',97227), +(1341,'Godhra','IND',96813), +(1342,'Hospet','IND',96322), +(1343,'Ashoknagar-Kalyangarh','IND',96315), +(1344,'Achalpur','IND',96216), +(1345,'Patan','IND',96109), +(1346,'Mandasor','IND',95758), +(1347,'Damoh','IND',95661), +(1348,'Satara','IND',95133), +(1349,'Meerut Cantonment','IND',94876), +(1350,'Dehri','IND',94526), +(1351,'Delhi Cantonment','IND',94326), +(1352,'Chhindwara','IND',93731), +(1353,'Bansberia','IND',93447), +(1354,'Nagaon','IND',93350), +(1355,'Kanpur Cantonment','IND',93109), +(1356,'Vidisha','IND',92917), +(1357,'Bettiah','IND',92583), +(1358,'Purulia','IND',92574), +(1359,'Hassan','IND',90803), +(1360,'Ambala Sadar','IND',90712), +(1361,'Baidyabati','IND',90601), +(1362,'Morvi','IND',90357), +(1363,'Raigarh','IND',89166), +(1364,'Vejalpur','IND',89053), +(1365,'Baghdad','IRQ',4336000), +(1366,'Mosul','IRQ',879000), +(1367,'Irbil','IRQ',485968), +(1368,'Kirkuk','IRQ',418624), +(1369,'Basra','IRQ',406296), +(1370,'al-Sulaymaniya','IRQ',364096), +(1371,'al-Najaf','IRQ',309010), +(1372,'Karbala','IRQ',296705), +(1373,'al-Hilla','IRQ',268834), +(1374,'al-Nasiriya','IRQ',265937), +(1375,'al-Amara','IRQ',208797), +(1376,'al-Diwaniya','IRQ',196519), +(1377,'al-Ramadi','IRQ',192556), +(1378,'al-Kut','IRQ',183183), +(1379,'Baquba','IRQ',114516), +(1380,'Teheran','IRN',6758845), +(1381,'Mashhad','IRN',1887405), +(1382,'Esfahan','IRN',1266072), +(1383,'Tabriz','IRN',1191043), +(1384,'Shiraz','IRN',1053025), +(1385,'Karaj','IRN',940968), +(1386,'Ahvaz','IRN',804980), +(1387,'Qom','IRN',777677), +(1388,'Kermanshah','IRN',692986), +(1389,'Urmia','IRN',435200), +(1390,'Zahedan','IRN',419518), +(1391,'Rasht','IRN',417748), +(1392,'Hamadan','IRN',401281), +(1393,'Kerman','IRN',384991), +(1394,'Arak','IRN',380755), +(1395,'Ardebil','IRN',340386), +(1396,'Yazd','IRN',326776), +(1397,'Qazvin','IRN',291117), +(1398,'Zanjan','IRN',286295), +(1399,'Sanandaj','IRN',277808), +(1400,'Bandar-e-Abbas','IRN',273578); +INSERT INTO City VALUES +(1401,'Khorramabad','IRN',272815), +(1402,'Eslamshahr','IRN',265450), +(1403,'Borujerd','IRN',217804), +(1404,'Abadan','IRN',206073), +(1405,'Dezful','IRN',202639), +(1406,'Kashan','IRN',201372), +(1407,'Sari','IRN',195882), +(1408,'Gorgan','IRN',188710), +(1409,'Najafabad','IRN',178498), +(1410,'Sabzevar','IRN',170738), +(1411,'Khomeynishahr','IRN',165888), +(1412,'Amol','IRN',159092), +(1413,'Neyshabur','IRN',158847), +(1414,'Babol','IRN',158346), +(1415,'Khoy','IRN',148944), +(1416,'Malayer','IRN',144373), +(1417,'Bushehr','IRN',143641), +(1418,'Qaemshahr','IRN',143286), +(1419,'Qarchak','IRN',142690), +(1420,'Qods','IRN',138278), +(1421,'Sirjan','IRN',135024), +(1422,'Bojnurd','IRN',134835), +(1423,'Maragheh','IRN',132318), +(1424,'Birjand','IRN',127608), +(1425,'Ilam','IRN',126346), +(1426,'Bukan','IRN',120020), +(1427,'Masjed-e-Soleyman','IRN',116883), +(1428,'Saqqez','IRN',115394), +(1429,'Gonbad-e Qabus','IRN',111253), +(1430,'Saveh','IRN',111245), +(1431,'Mahabad','IRN',107799), +(1432,'Varamin','IRN',107233), +(1433,'Andimeshk','IRN',106923), +(1434,'Khorramshahr','IRN',105636), +(1435,'Shahrud','IRN',104765), +(1436,'Marv Dasht','IRN',103579), +(1437,'Zabol','IRN',100887), +(1438,'Shahr-e Kord','IRN',100477), +(1439,'Bandar-e Anzali','IRN',98500), +(1440,'Rafsanjan','IRN',98300), +(1441,'Marand','IRN',96400), +(1442,'Torbat-e Heydariyeh','IRN',94600), +(1443,'Jahrom','IRN',94200), +(1444,'Semnan','IRN',91045), +(1445,'Miandoab','IRN',90100), +(1446,'Qomsheh','IRN',89800), +(1447,'Dublin','IRL',481854), +(1448,'Cork','IRL',127187), +(1449,'Reykjavík','ISL',109184), +(1450,'Jerusalem','ISR',633700), +(1451,'Tel Aviv-Jaffa','ISR',348100), +(1452,'Haifa','ISR',265700), +(1453,'Rishon Le Ziyyon','ISR',188200), +(1454,'Beerseba','ISR',163700), +(1455,'Holon','ISR',163100), +(1456,'Petah Tiqwa','ISR',159400), +(1457,'Ashdod','ISR',155800), +(1458,'Netanya','ISR',154900), +(1459,'Bat Yam','ISR',137000), +(1460,'Bene Beraq','ISR',133900), +(1461,'Ramat Gan','ISR',126900), +(1462,'Ashqelon','ISR',92300), +(1463,'Rehovot','ISR',90300), +(1464,'Roma','ITA',2643581), +(1465,'Milano','ITA',1300977), +(1466,'Napoli','ITA',1002619), +(1467,'Torino','ITA',903705), +(1468,'Palermo','ITA',683794), +(1469,'Genova','ITA',636104), +(1470,'Bologna','ITA',381161), +(1471,'Firenze','ITA',376662), +(1472,'Catania','ITA',337862), +(1473,'Bari','ITA',331848), +(1474,'Venezia','ITA',277305), +(1475,'Messina','ITA',259156), +(1476,'Verona','ITA',255268), +(1477,'Trieste','ITA',216459), +(1478,'Padova','ITA',211391), +(1479,'Taranto','ITA',208214), +(1480,'Brescia','ITA',191317), +(1481,'Reggio di Calabria','ITA',179617), +(1482,'Modena','ITA',176022), +(1483,'Prato','ITA',172473), +(1484,'Parma','ITA',168717), +(1485,'Cagliari','ITA',165926), +(1486,'Livorno','ITA',161673), +(1487,'Perugia','ITA',156673), +(1488,'Foggia','ITA',154891), +(1489,'Reggio nell´ Emilia','ITA',143664), +(1490,'Salerno','ITA',142055), +(1491,'Ravenna','ITA',138418), +(1492,'Ferrara','ITA',132127), +(1493,'Rimini','ITA',131062), +(1494,'Syrakusa','ITA',126282), +(1495,'Sassari','ITA',120803), +(1496,'Monza','ITA',119516), +(1497,'Bergamo','ITA',117837), +(1498,'Pescara','ITA',115698), +(1499,'Latina','ITA',114099), +(1500,'Vicenza','ITA',109738), +(1501,'Terni','ITA',107770), +(1502,'Forlì','ITA',107475), +(1503,'Trento','ITA',104906), +(1504,'Novara','ITA',102037), +(1505,'Piacenza','ITA',98384), +(1506,'Ancona','ITA',98329), +(1507,'Lecce','ITA',98208), +(1508,'Bolzano','ITA',97232), +(1509,'Catanzaro','ITA',96700), +(1510,'La Spezia','ITA',95504), +(1511,'Udine','ITA',94932), +(1512,'Torre del Greco','ITA',94505), +(1513,'Andria','ITA',94443), +(1514,'Brindisi','ITA',93454), +(1515,'Giugliano in Campania','ITA',93286), +(1516,'Pisa','ITA',92379), +(1517,'Barletta','ITA',91904), +(1518,'Arezzo','ITA',91729), +(1519,'Alessandria','ITA',90289), +(1520,'Cesena','ITA',89852), +(1521,'Pesaro','ITA',88987), +(1522,'Dili','TMP',47900), +(1523,'Wien','AUT',1608144), +(1524,'Graz','AUT',240967), +(1525,'Linz','AUT',188022), +(1526,'Salzburg','AUT',144247), +(1527,'Innsbruck','AUT',111752), +(1528,'Klagenfurt','AUT',91141), +(1529,'Spanish Town','JAM',110379), +(1530,'Kingston','JAM',103962), +(1531,'Portmore','JAM',99799), +(1532,'Tokyo','JPN',7980230), +(1533,'Jokohama [Yokohama]','JPN',3339594), +(1534,'Osaka','JPN',2595674), +(1535,'Nagoya','JPN',2154376), +(1536,'Sapporo','JPN',1790886), +(1537,'Kioto','JPN',1461974), +(1538,'Kobe','JPN',1425139), +(1539,'Fukuoka','JPN',1308379), +(1540,'Kawasaki','JPN',1217359), +(1541,'Hiroshima','JPN',1119117), +(1542,'Kitakyushu','JPN',1016264), +(1543,'Sendai','JPN',989975), +(1544,'Chiba','JPN',863930), +(1545,'Sakai','JPN',797735), +(1546,'Kumamoto','JPN',656734), +(1547,'Okayama','JPN',624269), +(1548,'Sagamihara','JPN',586300), +(1549,'Hamamatsu','JPN',568796), +(1550,'Kagoshima','JPN',549977), +(1551,'Funabashi','JPN',545299), +(1552,'Higashiosaka','JPN',517785), +(1553,'Hachioji','JPN',513451), +(1554,'Niigata','JPN',497464), +(1555,'Amagasaki','JPN',481434), +(1556,'Himeji','JPN',475167), +(1557,'Shizuoka','JPN',473854), +(1558,'Urawa','JPN',469675), +(1559,'Matsuyama','JPN',466133), +(1560,'Matsudo','JPN',461126), +(1561,'Kanazawa','JPN',455386), +(1562,'Kawaguchi','JPN',452155), +(1563,'Ichikawa','JPN',441893), +(1564,'Omiya','JPN',441649), +(1565,'Utsunomiya','JPN',440353), +(1566,'Oita','JPN',433401), +(1567,'Nagasaki','JPN',432759), +(1568,'Yokosuka','JPN',430200), +(1569,'Kurashiki','JPN',425103), +(1570,'Gifu','JPN',408007), +(1571,'Hirakata','JPN',403151), +(1572,'Nishinomiya','JPN',397618), +(1573,'Toyonaka','JPN',396689), +(1574,'Wakayama','JPN',391233), +(1575,'Fukuyama','JPN',376921), +(1576,'Fujisawa','JPN',372840), +(1577,'Asahikawa','JPN',364813), +(1578,'Machida','JPN',364197), +(1579,'Nara','JPN',362812), +(1580,'Takatsuki','JPN',361747), +(1581,'Iwaki','JPN',361737), +(1582,'Nagano','JPN',361391), +(1583,'Toyohashi','JPN',360066), +(1584,'Toyota','JPN',346090), +(1585,'Suita','JPN',345750), +(1586,'Takamatsu','JPN',332471), +(1587,'Koriyama','JPN',330335), +(1588,'Okazaki','JPN',328711), +(1589,'Kawagoe','JPN',327211), +(1590,'Tokorozawa','JPN',325809), +(1591,'Toyama','JPN',325790), +(1592,'Kochi','JPN',324710), +(1593,'Kashiwa','JPN',320296), +(1594,'Akita','JPN',314440), +(1595,'Miyazaki','JPN',303784), +(1596,'Koshigaya','JPN',301446), +(1597,'Naha','JPN',299851), +(1598,'Aomori','JPN',295969), +(1599,'Hakodate','JPN',294788), +(1600,'Akashi','JPN',292253); +INSERT INTO City VALUES +(1601,'Yokkaichi','JPN',288173), +(1602,'Fukushima','JPN',287525), +(1603,'Morioka','JPN',287353), +(1604,'Maebashi','JPN',284473), +(1605,'Kasugai','JPN',282348), +(1606,'Otsu','JPN',282070), +(1607,'Ichihara','JPN',279280), +(1608,'Yao','JPN',276421), +(1609,'Ichinomiya','JPN',270828), +(1610,'Tokushima','JPN',269649), +(1611,'Kakogawa','JPN',266281), +(1612,'Ibaraki','JPN',261020), +(1613,'Neyagawa','JPN',257315), +(1614,'Shimonoseki','JPN',257263), +(1615,'Yamagata','JPN',255617), +(1616,'Fukui','JPN',254818), +(1617,'Hiratsuka','JPN',254207), +(1618,'Mito','JPN',246559), +(1619,'Sasebo','JPN',244240), +(1620,'Hachinohe','JPN',242979), +(1621,'Takasaki','JPN',239124), +(1622,'Shimizu','JPN',239123), +(1623,'Kurume','JPN',235611), +(1624,'Fuji','JPN',231527), +(1625,'Soka','JPN',222768), +(1626,'Fuchu','JPN',220576), +(1627,'Chigasaki','JPN',216015), +(1628,'Atsugi','JPN',212407), +(1629,'Numazu','JPN',211382), +(1630,'Ageo','JPN',209442), +(1631,'Yamato','JPN',208234), +(1632,'Matsumoto','JPN',206801), +(1633,'Kure','JPN',206504), +(1634,'Takarazuka','JPN',205993), +(1635,'Kasukabe','JPN',201838), +(1636,'Chofu','JPN',201585), +(1637,'Odawara','JPN',200171), +(1638,'Kofu','JPN',199753), +(1639,'Kushiro','JPN',197608), +(1640,'Kishiwada','JPN',197276), +(1641,'Hitachi','JPN',196622), +(1642,'Nagaoka','JPN',192407), +(1643,'Itami','JPN',190886), +(1644,'Uji','JPN',188735), +(1645,'Suzuka','JPN',184061), +(1646,'Hirosaki','JPN',177522), +(1647,'Ube','JPN',175206), +(1648,'Kodaira','JPN',174984), +(1649,'Takaoka','JPN',174380), +(1650,'Obihiro','JPN',173685), +(1651,'Tomakomai','JPN',171958), +(1652,'Saga','JPN',170034), +(1653,'Sakura','JPN',168072), +(1654,'Kamakura','JPN',167661), +(1655,'Mitaka','JPN',167268), +(1656,'Izumi','JPN',166979), +(1657,'Hino','JPN',166770), +(1658,'Hadano','JPN',166512), +(1659,'Ashikaga','JPN',165243), +(1660,'Tsu','JPN',164543), +(1661,'Sayama','JPN',162472), +(1662,'Yachiyo','JPN',161222), +(1663,'Tsukuba','JPN',160768), +(1664,'Tachikawa','JPN',159430), +(1665,'Kumagaya','JPN',157171), +(1666,'Moriguchi','JPN',155941), +(1667,'Otaru','JPN',155784), +(1668,'Anjo','JPN',153823), +(1669,'Narashino','JPN',152849), +(1670,'Oyama','JPN',152820), +(1671,'Ogaki','JPN',151758), +(1672,'Matsue','JPN',149821), +(1673,'Kawanishi','JPN',149794), +(1674,'Hitachinaka','JPN',148006), +(1675,'Niiza','JPN',147744), +(1676,'Nagareyama','JPN',147738), +(1677,'Tottori','JPN',147523), +(1678,'Tama','JPN',146712), +(1679,'Iruma','JPN',145922), +(1680,'Ota','JPN',145317), +(1681,'Omuta','JPN',142889), +(1682,'Komaki','JPN',139827), +(1683,'Ome','JPN',139216), +(1684,'Kadoma','JPN',138953), +(1685,'Yamaguchi','JPN',138210), +(1686,'Higashimurayama','JPN',136970), +(1687,'Yonago','JPN',136461), +(1688,'Matsubara','JPN',135010), +(1689,'Musashino','JPN',134426), +(1690,'Tsuchiura','JPN',134072), +(1691,'Joetsu','JPN',133505), +(1692,'Miyakonojo','JPN',133183), +(1693,'Misato','JPN',132957), +(1694,'Kakamigahara','JPN',131831), +(1695,'Daito','JPN',130594), +(1696,'Seto','JPN',130470), +(1697,'Kariya','JPN',127969), +(1698,'Urayasu','JPN',127550), +(1699,'Beppu','JPN',127486), +(1700,'Niihama','JPN',127207), +(1701,'Minoo','JPN',127026), +(1702,'Fujieda','JPN',126897), +(1703,'Abiko','JPN',126670), +(1704,'Nobeoka','JPN',125547), +(1705,'Tondabayashi','JPN',125094), +(1706,'Ueda','JPN',124217), +(1707,'Kashihara','JPN',124013), +(1708,'Matsusaka','JPN',123582), +(1709,'Isesaki','JPN',123285), +(1710,'Zama','JPN',122046), +(1711,'Kisarazu','JPN',121967), +(1712,'Noda','JPN',121030), +(1713,'Ishinomaki','JPN',120963), +(1714,'Fujinomiya','JPN',119714), +(1715,'Kawachinagano','JPN',119666), +(1716,'Imabari','JPN',119357), +(1717,'Aizuwakamatsu','JPN',119287), +(1718,'Higashihiroshima','JPN',119166), +(1719,'Habikino','JPN',118968), +(1720,'Ebetsu','JPN',118805), +(1721,'Hofu','JPN',118751), +(1722,'Kiryu','JPN',118326), +(1723,'Okinawa','JPN',117748), +(1724,'Yaizu','JPN',117258), +(1725,'Toyokawa','JPN',115781), +(1726,'Ebina','JPN',115571), +(1727,'Asaka','JPN',114815), +(1728,'Higashikurume','JPN',111666), +(1729,'Ikoma','JPN',111645), +(1730,'Kitami','JPN',111295), +(1731,'Koganei','JPN',110969), +(1732,'Iwatsuki','JPN',110034), +(1733,'Mishima','JPN',109699), +(1734,'Handa','JPN',108600), +(1735,'Muroran','JPN',108275), +(1736,'Komatsu','JPN',107937), +(1737,'Yatsushiro','JPN',107661), +(1738,'Iida','JPN',107583), +(1739,'Tokuyama','JPN',107078), +(1740,'Kokubunji','JPN',106996), +(1741,'Akishima','JPN',106914), +(1742,'Iwakuni','JPN',106647), +(1743,'Kusatsu','JPN',106232), +(1744,'Kuwana','JPN',106121), +(1745,'Sanda','JPN',105643), +(1746,'Hikone','JPN',105508), +(1747,'Toda','JPN',103969), +(1748,'Tajimi','JPN',103171), +(1749,'Ikeda','JPN',102710), +(1750,'Fukaya','JPN',102156), +(1751,'Ise','JPN',101732), +(1752,'Sakata','JPN',101651), +(1753,'Kasuga','JPN',101344), +(1754,'Kamagaya','JPN',100821), +(1755,'Tsuruoka','JPN',100713), +(1756,'Hoya','JPN',100313), +(1757,'Nishio','JPN',100032), +(1758,'Tokai','JPN',99738), +(1759,'Inazawa','JPN',98746), +(1760,'Sakado','JPN',98221), +(1761,'Isehara','JPN',98123), +(1762,'Takasago','JPN',97632), +(1763,'Fujimi','JPN',96972), +(1764,'Urasoe','JPN',96002), +(1765,'Yonezawa','JPN',95592), +(1766,'Konan','JPN',95521), +(1767,'Yamatokoriyama','JPN',95165), +(1768,'Maizuru','JPN',94784), +(1769,'Onomichi','JPN',93756), +(1770,'Higashimatsuyama','JPN',93342), +(1771,'Kimitsu','JPN',93216), +(1772,'Isahaya','JPN',93058), +(1773,'Kanuma','JPN',93053), +(1774,'Izumisano','JPN',92583), +(1775,'Kameoka','JPN',92398), +(1776,'Mobara','JPN',91664), +(1777,'Narita','JPN',91470), +(1778,'Kashiwazaki','JPN',91229), +(1779,'Tsuyama','JPN',91170), +(1780,'Sanaa','YEM',503600), +(1781,'Aden','YEM',398300), +(1782,'Taizz','YEM',317600), +(1783,'Hodeida','YEM',298500), +(1784,'al-Mukalla','YEM',122400), +(1785,'Ibb','YEM',103300), +(1786,'Amman','JOR',1000000), +(1787,'al-Zarqa','JOR',389815), +(1788,'Irbid','JOR',231511), +(1789,'al-Rusayfa','JOR',137247), +(1790,'Wadi al-Sir','JOR',89104), +(1791,'Flying Fish Cove','CXR',700), +(1792,'Beograd','YUG',1204000), +(1793,'Novi Sad','YUG',179626), +(1794,'Niš','YUG',175391), +(1795,'Priština','YUG',155496), +(1796,'Kragujevac','YUG',147305), +(1797,'Podgorica','YUG',135000), +(1798,'Subotica','YUG',100386), +(1799,'Prizren','YUG',92303), +(1800,'Phnom Penh','KHM',570155); +INSERT INTO City VALUES +(1801,'Battambang','KHM',129800), +(1802,'Siem Reap','KHM',105100), +(1803,'Douala','CMR',1448300), +(1804,'Yaoundé','CMR',1372800), +(1805,'Garoua','CMR',177000), +(1806,'Maroua','CMR',143000), +(1807,'Bamenda','CMR',138000), +(1808,'Bafoussam','CMR',131000), +(1809,'Nkongsamba','CMR',112454), +(1810,'Montréal','CAN',1016376), +(1811,'Calgary','CAN',768082), +(1812,'Toronto','CAN',688275), +(1813,'North York','CAN',622632), +(1814,'Winnipeg','CAN',618477), +(1815,'Edmonton','CAN',616306), +(1816,'Mississauga','CAN',608072), +(1817,'Scarborough','CAN',594501), +(1818,'Vancouver','CAN',514008), +(1819,'Etobicoke','CAN',348845), +(1820,'London','CAN',339917), +(1821,'Hamilton','CAN',335614), +(1822,'Ottawa','CAN',335277), +(1823,'Laval','CAN',330393), +(1824,'Surrey','CAN',304477), +(1825,'Brampton','CAN',296711), +(1826,'Windsor','CAN',207588), +(1827,'Saskatoon','CAN',193647), +(1828,'Kitchener','CAN',189959), +(1829,'Markham','CAN',189098), +(1830,'Regina','CAN',180400), +(1831,'Burnaby','CAN',179209), +(1832,'Québec','CAN',167264), +(1833,'York','CAN',154980), +(1834,'Richmond','CAN',148867), +(1835,'Vaughan','CAN',147889), +(1836,'Burlington','CAN',145150), +(1837,'Oshawa','CAN',140173), +(1838,'Oakville','CAN',139192), +(1839,'Saint Catharines','CAN',136216), +(1840,'Longueuil','CAN',127977), +(1841,'Richmond Hill','CAN',116428), +(1842,'Thunder Bay','CAN',115913), +(1843,'Nepean','CAN',115100), +(1844,'Cape Breton','CAN',114733), +(1845,'East York','CAN',114034), +(1846,'Halifax','CAN',113910), +(1847,'Cambridge','CAN',109186), +(1848,'Gloucester','CAN',107314), +(1849,'Abbotsford','CAN',105403), +(1850,'Guelph','CAN',103593), +(1851,'Saint John´s','CAN',101936), +(1852,'Coquitlam','CAN',101820), +(1853,'Saanich','CAN',101388), +(1854,'Gatineau','CAN',100702), +(1855,'Delta','CAN',95411), +(1856,'Sudbury','CAN',92686), +(1857,'Kelowna','CAN',89442), +(1858,'Barrie','CAN',89269), +(1859,'Praia','CPV',94800), +(1860,'Almaty','KAZ',1129400), +(1861,'Qaraghandy','KAZ',436900), +(1862,'Shymkent','KAZ',360100), +(1863,'Taraz','KAZ',330100), +(1864,'Astana','KAZ',311200), +(1865,'Öskemen','KAZ',311000), +(1866,'Pavlodar','KAZ',300500), +(1867,'Semey','KAZ',269600), +(1868,'Aqtöbe','KAZ',253100), +(1869,'Qostanay','KAZ',221400), +(1870,'Petropavl','KAZ',203500), +(1871,'Oral','KAZ',195500), +(1872,'Temirtau','KAZ',170500), +(1873,'Qyzylorda','KAZ',157400), +(1874,'Aqtau','KAZ',143400), +(1875,'Atyrau','KAZ',142500), +(1876,'Ekibastuz','KAZ',127200), +(1877,'Kökshetau','KAZ',123400), +(1878,'Rudnyy','KAZ',109500), +(1879,'Taldyqorghan','KAZ',98000), +(1880,'Zhezqazghan','KAZ',90000), +(1881,'Nairobi','KEN',2290000), +(1882,'Mombasa','KEN',461753), +(1883,'Kisumu','KEN',192733), +(1884,'Nakuru','KEN',163927), +(1885,'Machakos','KEN',116293), +(1886,'Eldoret','KEN',111882), +(1887,'Meru','KEN',94947), +(1888,'Nyeri','KEN',91258), +(1889,'Bangui','CAF',524000), +(1890,'Shanghai','CHN',9696300), +(1891,'Peking','CHN',7472000), +(1892,'Chongqing','CHN',6351600), +(1893,'Tianjin','CHN',5286800), +(1894,'Wuhan','CHN',4344600), +(1895,'Harbin','CHN',4289800), +(1896,'Shenyang','CHN',4265200), +(1897,'Kanton [Guangzhou]','CHN',4256300), +(1898,'Chengdu','CHN',3361500), +(1899,'Nanking [Nanjing]','CHN',2870300), +(1900,'Changchun','CHN',2812000), +(1901,'Xi´an','CHN',2761400), +(1902,'Dalian','CHN',2697000), +(1903,'Qingdao','CHN',2596000), +(1904,'Jinan','CHN',2278100), +(1905,'Hangzhou','CHN',2190500), +(1906,'Zhengzhou','CHN',2107200), +(1907,'Shijiazhuang','CHN',2041500), +(1908,'Taiyuan','CHN',1968400), +(1909,'Kunming','CHN',1829500), +(1910,'Changsha','CHN',1809800), +(1911,'Nanchang','CHN',1691600), +(1912,'Fuzhou','CHN',1593800), +(1913,'Lanzhou','CHN',1565800), +(1914,'Guiyang','CHN',1465200), +(1915,'Ningbo','CHN',1371200), +(1916,'Hefei','CHN',1369100), +(1917,'Urumtši [Ürümqi]','CHN',1310100), +(1918,'Anshan','CHN',1200000), +(1919,'Fushun','CHN',1200000), +(1920,'Nanning','CHN',1161800), +(1921,'Zibo','CHN',1140000), +(1922,'Qiqihar','CHN',1070000), +(1923,'Jilin','CHN',1040000), +(1924,'Tangshan','CHN',1040000), +(1925,'Baotou','CHN',980000), +(1926,'Shenzhen','CHN',950500), +(1927,'Hohhot','CHN',916700), +(1928,'Handan','CHN',840000), +(1929,'Wuxi','CHN',830000), +(1930,'Xuzhou','CHN',810000), +(1931,'Datong','CHN',800000), +(1932,'Yichun','CHN',800000), +(1933,'Benxi','CHN',770000), +(1934,'Luoyang','CHN',760000), +(1935,'Suzhou','CHN',710000), +(1936,'Xining','CHN',700200), +(1937,'Huainan','CHN',700000), +(1938,'Jixi','CHN',683885), +(1939,'Daqing','CHN',660000), +(1940,'Fuxin','CHN',640000), +(1941,'Amoy [Xiamen]','CHN',627500), +(1942,'Liuzhou','CHN',610000), +(1943,'Shantou','CHN',580000), +(1944,'Jinzhou','CHN',570000), +(1945,'Mudanjiang','CHN',570000), +(1946,'Yinchuan','CHN',544500), +(1947,'Changzhou','CHN',530000), +(1948,'Zhangjiakou','CHN',530000), +(1949,'Dandong','CHN',520000), +(1950,'Hegang','CHN',520000), +(1951,'Kaifeng','CHN',510000), +(1952,'Jiamusi','CHN',493409), +(1953,'Liaoyang','CHN',492559), +(1954,'Hengyang','CHN',487148), +(1955,'Baoding','CHN',483155), +(1956,'Hunjiang','CHN',482043), +(1957,'Xinxiang','CHN',473762), +(1958,'Huangshi','CHN',457601), +(1959,'Haikou','CHN',454300), +(1960,'Yantai','CHN',452127), +(1961,'Bengbu','CHN',449245), +(1962,'Xiangtan','CHN',441968), +(1963,'Weifang','CHN',428522), + (1964,'Wuhu','CHN',425740), +(1965,'Pingxiang','CHN',425579), +(1966,'Yingkou','CHN',421589), +(1967,'Anyang','CHN',420332), +(1968,'Panzhihua','CHN',415466), +(1969,'Pingdingshan','CHN',410775), +(1970,'Xiangfan','CHN',410407), +(1971,'Zhuzhou','CHN',409924), +(1972,'Jiaozuo','CHN',409100), +(1973,'Wenzhou','CHN',401871), +(1974,'Zhangjiang','CHN',400997), +(1975,'Zigong','CHN',393184), +(1976,'Shuangyashan','CHN',386081), +(1977,'Zaozhuang','CHN',380846), +(1978,'Yakeshi','CHN',377869), +(1979,'Yichang','CHN',371601), +(1980,'Zhenjiang','CHN',368316), +(1981,'Huaibei','CHN',366549), +(1982,'Qinhuangdao','CHN',364972), +(1983,'Guilin','CHN',364130), +(1984,'Liupanshui','CHN',363954), +(1985,'Panjin','CHN',362773), +(1986,'Yangquan','CHN',362268), +(1987,'Jinxi','CHN',357052), +(1988,'Liaoyuan','CHN',354141), +(1989,'Lianyungang','CHN',354139), +(1990,'Xianyang','CHN',352125), +(1991,'Tai´an','CHN',350696), +(1992,'Chifeng','CHN',350077), +(1993,'Shaoguan','CHN',350043), +(1994,'Nantong','CHN',343341), +(1995,'Leshan','CHN',341128), +(1996,'Baoji','CHN',337765), +(1997,'Linyi','CHN',324720), +(1998,'Tonghua','CHN',324600), +(1999,'Siping','CHN',317223), +(2000,'Changzhi','CHN',317144); +INSERT INTO City VALUES +(2001,'Tengzhou','CHN',315083), +(2002,'Chaozhou','CHN',313469), +(2003,'Yangzhou','CHN',312892), +(2004,'Dongwan','CHN',308669), +(2005,'Ma´anshan','CHN',305421), +(2006,'Foshan','CHN',303160), +(2007,'Yueyang','CHN',302800), +(2008,'Xingtai','CHN',302789), +(2009,'Changde','CHN',301276), +(2010,'Shihezi','CHN',299676), +(2011,'Yancheng','CHN',296831), +(2012,'Jiujiang','CHN',291187), +(2013,'Dongying','CHN',281728), +(2014,'Shashi','CHN',281352), +(2015,'Xintai','CHN',281248), +(2016,'Jingdezhen','CHN',281183), +(2017,'Tongchuan','CHN',280657), +(2018,'Zhongshan','CHN',278829), +(2019,'Shiyan','CHN',273786), +(2020,'Tieli','CHN',265683), +(2021,'Jining','CHN',265248), +(2022,'Wuhai','CHN',264081), +(2023,'Mianyang','CHN',262947), +(2024,'Luzhou','CHN',262892), +(2025,'Zunyi','CHN',261862), +(2026,'Shizuishan','CHN',257862), +(2027,'Neijiang','CHN',256012), +(2028,'Tongliao','CHN',255129), +(2029,'Tieling','CHN',254842), +(2030,'Wafangdian','CHN',251733), +(2031,'Anqing','CHN',250718), +(2032,'Shaoyang','CHN',247227), +(2033,'Laiwu','CHN',246833), +(2034,'Chengde','CHN',246799), +(2035,'Tianshui','CHN',244974), +(2036,'Nanyang','CHN',243303), +(2037,'Cangzhou','CHN',242708), +(2038,'Yibin','CHN',241019), +(2039,'Huaiyin','CHN',239675), +(2040,'Dunhua','CHN',235100), +(2041,'Yanji','CHN',230892), +(2042,'Jiangmen','CHN',230587), +(2043,'Tongling','CHN',228017), +(2044,'Suihua','CHN',227881), +(2045,'Gongziling','CHN',226569), +(2046,'Xiantao','CHN',222884), +(2047,'Chaoyang','CHN',222394), +(2048,'Ganzhou','CHN',220129), +(2049,'Huzhou','CHN',218071), +(2050,'Baicheng','CHN',217987), +(2051,'Shangzi','CHN',215373), +(2052,'Yangjiang','CHN',215196), +(2053,'Qitaihe','CHN',214957), +(2054,'Gejiu','CHN',214294), +(2055,'Jiangyin','CHN',213659), +(2056,'Hebi','CHN',212976), +(2057,'Jiaxing','CHN',211526), +(2058,'Wuzhou','CHN',210452), +(2059,'Meihekou','CHN',209038), +(2060,'Xuchang','CHN',208815), +(2061,'Liaocheng','CHN',207844), +(2062,'Haicheng','CHN',205560), +(2063,'Qianjiang','CHN',205504), +(2064,'Baiyin','CHN',204970), +(2065,'Bei´an','CHN',204899), +(2066,'Yixing','CHN',200824), +(2067,'Laizhou','CHN',198664), +(2068,'Qaramay','CHN',197602), +(2069,'Acheng','CHN',197595), +(2070,'Dezhou','CHN',195485), +(2071,'Nanping','CHN',195064), +(2072,'Zhaoqing','CHN',194784), +(2073,'Beipiao','CHN',194301), +(2074,'Fengcheng','CHN',193784), +(2075,'Fuyu','CHN',192981), +(2076,'Xinyang','CHN',192509), +(2077,'Dongtai','CHN',192247), +(2078,'Yuci','CHN',191356), +(2079,'Honghu','CHN',190772), +(2080,'Ezhou','CHN',190123), +(2081,'Heze','CHN',189293), +(2082,'Daxian','CHN',188101), +(2083,'Linfen','CHN',187309), +(2084,'Tianmen','CHN',186332), +(2085,'Yiyang','CHN',185818), +(2086,'Quanzhou','CHN',185154), +(2087,'Rizhao','CHN',185048), +(2088,'Deyang','CHN',182488), +(2089,'Guangyuan','CHN',182241), +(2090,'Changshu','CHN',181805), +(2091,'Zhangzhou','CHN',181424), +(2092,'Hailar','CHN',180650), +(2093,'Nanchong','CHN',180273), +(2094,'Jiutai','CHN',180130), +(2095,'Zhaodong','CHN',179976), +(2096,'Shaoxing','CHN',179818), +(2097,'Fuyang','CHN',179572), +(2098,'Maoming','CHN',178683), +(2099,'Qujing','CHN',178669), +(2100,'Ghulja','CHN',177193), +(2101,'Jiaohe','CHN',176367), +(2102,'Puyang','CHN',175988), +(2103,'Huadian','CHN',175873), +(2104,'Jiangyou','CHN',175753), +(2105,'Qashqar','CHN',174570), +(2106,'Anshun','CHN',174142), +(2107,'Fuling','CHN',173878), +(2108,'Xinyu','CHN',173524), +(2109,'Hanzhong','CHN',169930), +(2110,'Danyang','CHN',169603), +(2111,'Chenzhou','CHN',169400), +(2112,'Xiaogan','CHN',166280), +(2113,'Shangqiu','CHN',164880), +(2114,'Zhuhai','CHN',164747), +(2115,'Qingyuan','CHN',164641), +(2116,'Aqsu','CHN',164092), +(2117,'Jining','CHN',163552), +(2118,'Xiaoshan','CHN',162930), +(2119,'Zaoyang','CHN',162198), +(2120,'Xinghua','CHN',161910), +(2121,'Hami','CHN',161315), +(2122,'Huizhou','CHN',161023), +(2123,'Jinmen','CHN',160794), +(2124,'Sanming','CHN',160691), +(2125,'Ulanhot','CHN',159538), +(2126,'Korla','CHN',159344), +(2127,'Wanxian','CHN',156823), +(2128,'Rui´an','CHN',156468), +(2129,'Zhoushan','CHN',156317), +(2130,'Liangcheng','CHN',156307), +(2131,'Jiaozhou','CHN',153364), +(2132,'Taizhou','CHN',152442), +(2133,'Suzhou','CHN',151862), +(2134,'Yichun','CHN',151585), +(2135,'Taonan','CHN',150168), +(2136,'Pingdu','CHN',150123), +(2137,'Ji´an','CHN',148583), +(2138,'Longkou','CHN',148362), +(2139,'Langfang','CHN',148105), +(2140,'Zhoukou','CHN',146288), +(2141,'Suining','CHN',146086), +(2142,'Yulin','CHN',144467), +(2143,'Jinhua','CHN',144280), +(2144,'Liu´an','CHN',144248), +(2145,'Shuangcheng','CHN',142659), +(2146,'Suizhou','CHN',142302), +(2147,'Ankang','CHN',142170), +(2148,'Weinan','CHN',140169), +(2149,'Longjing','CHN',139417), +(2150,'Da´an','CHN',138963), +(2151,'Lengshuijiang','CHN',137994), +(2152,'Laiyang','CHN',137080), +(2153,'Xianning','CHN',136811), +(2154,'Dali','CHN',136554), +(2155,'Anda','CHN',136446), +(2156,'Jincheng','CHN',136396), +(2157,'Longyan','CHN',134481), +(2158,'Xichang','CHN',134419), +(2159,'Wendeng','CHN',133910), +(2160,'Hailun','CHN',133565), +(2161,'Binzhou','CHN',133555), +(2162,'Linhe','CHN',133183), +(2163,'Wuwei','CHN',133101), +(2164,'Duyun','CHN',132971), +(2165,'Mishan','CHN',132744), +(2166,'Shangrao','CHN',132455), +(2167,'Changji','CHN',132260), +(2168,'Meixian','CHN',132156), +(2169,'Yushu','CHN',131861), +(2170,'Tiefa','CHN',131807), +(2171,'Huai´an','CHN',131149), +(2172,'Leiyang','CHN',130115), +(2173,'Zalantun','CHN',130031), +(2174,'Weihai','CHN',128888), +(2175,'Loudi','CHN',128418), +(2176,'Qingzhou','CHN',128258), +(2177,'Qidong','CHN',126872), +(2178,'Huaihua','CHN',126785), +(2179,'Luohe','CHN',126438), +(2180,'Chuzhou','CHN',125341), +(2181,'Kaiyuan','CHN',124219), +(2182,'Linqing','CHN',123958), +(2183,'Chaohu','CHN',123676), +(2184,'Laohekou','CHN',123366), +(2185,'Dujiangyan','CHN',123357), +(2186,'Zhumadian','CHN',123232), +(2187,'Linchuan','CHN',121949), +(2188,'Jiaonan','CHN',121397), +(2189,'Sanmenxia','CHN',120523), +(2190,'Heyuan','CHN',120101), +(2191,'Manzhouli','CHN',120023), +(2192,'Lhasa','CHN',120000), +(2193,'Lianyuan','CHN',118858), +(2194,'Kuytun','CHN',118553), +(2195,'Puqi','CHN',117264), +(2196,'Hongjiang','CHN',116188), +(2197,'Qinzhou','CHN',114586), +(2198,'Renqiu','CHN',114256), +(2199,'Yuyao','CHN',114065), +(2200,'Guigang','CHN',114025); +INSERT INTO City VALUES +(2201,'Kaili','CHN',113958), +(2202,'Yan´an','CHN',113277), +(2203,'Beihai','CHN',112673), +(2204,'Xuangzhou','CHN',112673), +(2205,'Quzhou','CHN',112373), +(2206,'Yong´an','CHN',111762), +(2207,'Zixing','CHN',110048), +(2208,'Liyang','CHN',109520), +(2209,'Yizheng','CHN',109268), +(2210,'Yumen','CHN',109234), +(2211,'Liling','CHN',108504), +(2212,'Yuncheng','CHN',108359), +(2213,'Shanwei','CHN',107847), +(2214,'Cixi','CHN',107329), +(2215,'Yuanjiang','CHN',107004), +(2216,'Bozhou','CHN',106346), +(2217,'Jinchang','CHN',105287), +(2218,'Fu´an','CHN',105265), +(2219,'Suqian','CHN',105021), +(2220,'Shishou','CHN',104571), +(2221,'Hengshui','CHN',104269), +(2222,'Danjiangkou','CHN',103211), +(2223,'Fujin','CHN',103104), +(2224,'Sanya','CHN',102820), +(2225,'Guangshui','CHN',102770), +(2226,'Huangshan','CHN',102628), +(2227,'Xingcheng','CHN',102384), +(2228,'Zhucheng','CHN',102134), +(2229,'Kunshan','CHN',102052), +(2230,'Haining','CHN',100478), +(2231,'Pingliang','CHN',99265), +(2232,'Fuqing','CHN',99193), +(2233,'Xinzhou','CHN',98667), +(2234,'Jieyang','CHN',98531), +(2235,'Zhangjiagang','CHN',97994), +(2236,'Tong Xian','CHN',97168), +(2237,'Ya´an','CHN',95900), +(2238,'Jinzhou','CHN',95761), +(2239,'Emeishan','CHN',94000), +(2240,'Enshi','CHN',93056), +(2241,'Bose','CHN',93009), +(2242,'Yuzhou','CHN',92889), +(2243,'Kaiyuan','CHN',91999), +(2244,'Tumen','CHN',91471), +(2245,'Putian','CHN',91030), +(2246,'Linhai','CHN',90870), +(2247,'Xilin Hot','CHN',90646), +(2248,'Shaowu','CHN',90286), +(2249,'Junan','CHN',90222), +(2250,'Huaying','CHN',89400), +(2251,'Pingyi','CHN',89373), +(2252,'Huangyan','CHN',89288), +(2253,'Bishkek','KGZ',589400), +(2254,'Osh','KGZ',222700), +(2255,'Bikenibeu','KIR',5055), +(2256,'Bairiki','KIR',2226), +(2257,'Santafé de Bogotá','COL',6260862), +(2258,'Cali','COL',2077386), +(2259,'Medellín','COL',1861265), +(2260,'Barranquilla','COL',1223260), +(2261,'Cartagena','COL',805757), +(2262,'Cúcuta','COL',606932), +(2263,'Bucaramanga','COL',515555), +(2264,'Ibagué','COL',393664), +(2265,'Pereira','COL',381725), +(2266,'Santa Marta','COL',359147), +(2267,'Manizales','COL',337580), +(2268,'Bello','COL',333470), +(2269,'Pasto','COL',332396), +(2270,'Neiva','COL',300052), +(2271,'Soledad','COL',295058), +(2272,'Armenia','COL',288977), +(2273,'Villavicencio','COL',273140), +(2274,'Soacha','COL',272058), +(2275,'Valledupar','COL',263247), +(2276,'Montería','COL',248245), +(2277,'Itagüí','COL',228985), +(2278,'Palmira','COL',226509), +(2279,'Buenaventura','COL',224336), +(2280,'Floridablanca','COL',221913), +(2281,'Sincelejo','COL',220704), +(2282,'Popayán','COL',200719), +(2283,'Barrancabermeja','COL',178020), +(2284,'Dos Quebradas','COL',159363), +(2285,'Tuluá','COL',152488), +(2286,'Envigado','COL',135848), +(2287,'Cartago','COL',125884), +(2288,'Girardot','COL',110963), +(2289,'Buga','COL',110699), +(2290,'Tunja','COL',109740), +(2291,'Florencia','COL',108574), +(2292,'Maicao','COL',108053), +(2293,'Sogamoso','COL',107728), +(2294,'Giron','COL',90688), +(2295,'Moroni','COM',36000), +(2296,'Brazzaville','COG',950000), +(2297,'Pointe-Noire','COG',500000), +(2298,'Kinshasa','COD',5064000), +(2299,'Lubumbashi','COD',851381), +(2300,'Mbuji-Mayi','COD',806475), +(2301,'Kolwezi','COD',417810), +(2302,'Kisangani','COD',417517), +(2303,'Kananga','COD',393030), +(2304,'Likasi','COD',299118), +(2305,'Bukavu','COD',201569), +(2306,'Kikwit','COD',182142), +(2307,'Tshikapa','COD',180860), +(2308,'Matadi','COD',172730), +(2309,'Mbandaka','COD',169841), +(2310,'Mwene-Ditu','COD',137459), +(2311,'Boma','COD',135284), +(2312,'Uvira','COD',115590), +(2313,'Butembo','COD',109406), +(2314,'Goma','COD',109094), +(2315,'Kalemie','COD',101309), +(2316,'Bantam','CCK',503), +(2317,'West Island','CCK',167), +(2318,'Pyongyang','PRK',2484000), +(2319,'Hamhung','PRK',709730), +(2320,'Chongjin','PRK',582480), +(2321,'Nampo','PRK',566200), +(2322,'Sinuiju','PRK',326011), +(2323,'Wonsan','PRK',300148), +(2324,'Phyongsong','PRK',272934), +(2325,'Sariwon','PRK',254146), +(2326,'Haeju','PRK',229172), +(2327,'Kanggye','PRK',223410), +(2328,'Kimchaek','PRK',179000), +(2329,'Hyesan','PRK',178020), +(2330,'Kaesong','PRK',171500), +(2331,'Seoul','KOR',9981619), +(2332,'Pusan','KOR',3804522), +(2333,'Inchon','KOR',2559424), +(2334,'Taegu','KOR',2548568), +(2335,'Taejon','KOR',1425835), +(2336,'Kwangju','KOR',1368341), +(2337,'Ulsan','KOR',1084891), +(2338,'Songnam','KOR',869094), +(2339,'Puchon','KOR',779412), +(2340,'Suwon','KOR',755550), +(2341,'Anyang','KOR',591106), +(2342,'Chonju','KOR',563153), +(2343,'Chongju','KOR',531376), +(2344,'Koyang','KOR',518282), +(2345,'Ansan','KOR',510314), +(2346,'Pohang','KOR',508899), +(2347,'Chang-won','KOR',481694), +(2348,'Masan','KOR',441242), +(2349,'Kwangmyong','KOR',350914), +(2350,'Chonan','KOR',330259), +(2351,'Chinju','KOR',329886), +(2352,'Iksan','KOR',322685), +(2353,'Pyongtaek','KOR',312927), +(2354,'Kumi','KOR',311431), +(2355,'Uijongbu','KOR',276111), +(2356,'Kyongju','KOR',272968), +(2357,'Kunsan','KOR',266569), +(2358,'Cheju','KOR',258511), +(2359,'Kimhae','KOR',256370), +(2360,'Sunchon','KOR',249263), +(2361,'Mokpo','KOR',247452), +(2362,'Yong-in','KOR',242643), +(2363,'Wonju','KOR',237460), +(2364,'Kunpo','KOR',235233), +(2365,'Chunchon','KOR',234528), +(2366,'Namyangju','KOR',229060), +(2367,'Kangnung','KOR',220403), +(2368,'Chungju','KOR',205206), +(2369,'Andong','KOR',188443), +(2370,'Yosu','KOR',183596), +(2371,'Kyongsan','KOR',173746), +(2372,'Paju','KOR',163379), +(2373,'Yangsan','KOR',163351), +(2374,'Ichon','KOR',155332), +(2375,'Asan','KOR',154663), +(2376,'Koje','KOR',147562), +(2377,'Kimchon','KOR',147027), +(2378,'Nonsan','KOR',146619), +(2379,'Kuri','KOR',142173), +(2380,'Chong-up','KOR',139111), +(2381,'Chechon','KOR',137070), +(2382,'Sosan','KOR',134746), +(2383,'Shihung','KOR',133443), +(2384,'Tong-yong','KOR',131717), +(2385,'Kongju','KOR',131229), +(2386,'Yongju','KOR',131097), +(2387,'Chinhae','KOR',125997), +(2388,'Sangju','KOR',124116), +(2389,'Poryong','KOR',122604), +(2390,'Kwang-yang','KOR',122052), +(2391,'Miryang','KOR',121501), +(2392,'Hanam','KOR',115812), +(2393,'Kimje','KOR',115427), +(2394,'Yongchon','KOR',113511), +(2395,'Sachon','KOR',113494), +(2396,'Uiwang','KOR',108788), +(2397,'Naju','KOR',107831), +(2398,'Namwon','KOR',103544), +(2399,'Tonghae','KOR',95472), +(2400,'Mun-gyong','KOR',92239); +INSERT INTO City VALUES +(2401,'Athenai','GRC',772072), +(2402,'Thessaloniki','GRC',383967), +(2403,'Pireus','GRC',182671), +(2404,'Patras','GRC',153344), +(2405,'Peristerion','GRC',137288), +(2406,'Herakleion','GRC',116178), +(2407,'Kallithea','GRC',114233), +(2408,'Larisa','GRC',113090), +(2409,'Zagreb','HRV',706770), +(2410,'Split','HRV',189388), +(2411,'Rijeka','HRV',167964), +(2412,'Osijek','HRV',104761), +(2413,'La Habana','CUB',2256000), +(2414,'Santiago de Cuba','CUB',433180), +(2415,'Camagüey','CUB',298726), +(2416,'Holguín','CUB',249492), +(2417,'Santa Clara','CUB',207350), +(2418,'Guantánamo','CUB',205078), +(2419,'Pinar del Río','CUB',142100), +(2420,'Bayamo','CUB',141000), +(2421,'Cienfuegos','CUB',132770), +(2422,'Victoria de las Tunas','CUB',132350), +(2423,'Matanzas','CUB',123273), +(2424,'Manzanillo','CUB',109350), +(2425,'Sancti-Spíritus','CUB',100751), +(2426,'Ciego de Ávila','CUB',98505), +(2427,'al-Salimiya','KWT',130215), +(2428,'Jalib al-Shuyukh','KWT',102178), +(2429,'Kuwait','KWT',28859), +(2430,'Nicosia','CYP',195000), +(2431,'Limassol','CYP',154400), +(2432,'Vientiane','LAO',531800), +(2433,'Savannakhet','LAO',96652), +(2434,'Riga','LVA',764328), +(2435,'Daugavpils','LVA',114829), +(2436,'Liepaja','LVA',89439), +(2437,'Maseru','LSO',297000), +(2438,'Beirut','LBN',1100000), +(2439,'Tripoli','LBN',240000), +(2440,'Monrovia','LBR',850000), +(2441,'Tripoli','LBY',1682000), +(2442,'Bengasi','LBY',804000), +(2443,'Misrata','LBY',121669), +(2444,'al-Zawiya','LBY',89338), +(2445,'Schaan','LIE',5346), +(2446,'Vaduz','LIE',5043), +(2447,'Vilnius','LTU',577969), +(2448,'Kaunas','LTU',412639), +(2449,'Klaipeda','LTU',202451), +(2450,'Šiauliai','LTU',146563), +(2451,'Panevezys','LTU',133695), +(2452,'Luxembourg [Luxemburg/Lëtzebuerg]','LUX',80700), +(2453,'El-Aaiún','ESH',169000), +(2454,'Macao','MAC',437500), +(2455,'Antananarivo','MDG',675669), +(2456,'Toamasina','MDG',127441), +(2457,'Antsirabé','MDG',120239), +(2458,'Mahajanga','MDG',100807), +(2459,'Fianarantsoa','MDG',99005), +(2460,'Skopje','MKD',444299), +(2461,'Blantyre','MWI',478155), +(2462,'Lilongwe','MWI',435964), +(2463,'Male','MDV',71000), +(2464,'Kuala Lumpur','MYS',1297526), +(2465,'Ipoh','MYS',382853), +(2466,'Johor Baharu','MYS',328436), +(2467,'Petaling Jaya','MYS',254350), +(2468,'Kelang','MYS',243355), +(2469,'Kuala Terengganu','MYS',228119), +(2470,'Pinang','MYS',219603), +(2471,'Kota Bharu','MYS',219582), +(2472,'Kuantan','MYS',199484), +(2473,'Taiping','MYS',183261), +(2474,'Seremban','MYS',182869), +(2475,'Kuching','MYS',148059), +(2476,'Sibu','MYS',126381), +(2477,'Sandakan','MYS',125841), +(2478,'Alor Setar','MYS',124412), +(2479,'Selayang Baru','MYS',124228), +(2480,'Sungai Petani','MYS',114763), +(2481,'Shah Alam','MYS',102019), +(2482,'Bamako','MLI',809552), +(2483,'Birkirkara','MLT',21445), +(2484,'Valletta','MLT',7073), +(2485,'Casablanca','MAR',2940623), +(2486,'Rabat','MAR',623457), +(2487,'Marrakech','MAR',621914), +(2488,'Fès','MAR',541162), +(2489,'Tanger','MAR',521735), +(2490,'Salé','MAR',504420), +(2491,'Meknès','MAR',460000), +(2492,'Oujda','MAR',365382), +(2493,'Kénitra','MAR',292600), +(2494,'Tétouan','MAR',277516), +(2495,'Safi','MAR',262300), +(2496,'Agadir','MAR',155244), +(2497,'Mohammedia','MAR',154706), +(2498,'Khouribga','MAR',152090), +(2499,'Beni-Mellal','MAR',140212), +(2500,'Témara','MAR',126303), +(2501,'El Jadida','MAR',119083), +(2502,'Nador','MAR',112450), +(2503,'Ksar el Kebir','MAR',107065), +(2504,'Settat','MAR',96200), +(2505,'Taza','MAR',92700), +(2506,'El Araich','MAR',90400), +(2507,'Dalap-Uliga-Darrit','MHL',28000), +(2508,'Fort-de-France','MTQ',94050), +(2509,'Nouakchott','MRT',667300), +(2510,'Nouâdhibou','MRT',97600), +(2511,'Port-Louis','MUS',138200), +(2512,'Beau Bassin-Rose Hill','MUS',100616), +(2513,'Vacoas-Phoenix','MUS',98464), +(2514,'Mamoutzou','MYT',12000), +(2515,'Ciudad de México','MEX',8591309), +(2516,'Guadalajara','MEX',1647720), +(2517,'Ecatepec de Morelos','MEX',1620303), +(2518,'Puebla','MEX',1346176), +(2519,'Nezahualcóyotl','MEX',1224924), +(2520,'Juárez','MEX',1217818), +(2521,'Tijuana','MEX',1212232), +(2522,'León','MEX',1133576), +(2523,'Monterrey','MEX',1108499), +(2524,'Zapopan','MEX',1002239), +(2525,'Naucalpan de Juárez','MEX',857511), +(2526,'Mexicali','MEX',764902), +(2527,'Culiacán','MEX',744859), +(2528,'Acapulco de Juárez','MEX',721011), +(2529,'Tlalnepantla de Baz','MEX',720755), +(2530,'Mérida','MEX',703324), +(2531,'Chihuahua','MEX',670208), +(2532,'San Luis Potosí','MEX',669353), +(2533,'Guadalupe','MEX',668780), +(2534,'Toluca','MEX',665617), +(2535,'Aguascalientes','MEX',643360), +(2536,'Querétaro','MEX',639839), +(2537,'Morelia','MEX',619958), +(2538,'Hermosillo','MEX',608697), +(2539,'Saltillo','MEX',577352), +(2540,'Torreón','MEX',529093), +(2541,'Centro (Villahermosa)','MEX',519873), +(2542,'San Nicolás de los Garza','MEX',495540), +(2543,'Durango','MEX',490524), +(2544,'Chimalhuacán','MEX',490245), +(2545,'Tlaquepaque','MEX',475472), +(2546,'Atizapán de Zaragoza','MEX',467262), +(2547,'Veracruz','MEX',457119), +(2548,'Cuautitlán Izcalli','MEX',452976), +(2549,'Irapuato','MEX',440039), +(2550,'Tuxtla Gutiérrez','MEX',433544), +(2551,'Tultitlán','MEX',432411), +(2552,'Reynosa','MEX',419776), +(2553,'Benito Juárez','MEX',419276), +(2554,'Matamoros','MEX',416428), +(2555,'Xalapa','MEX',390058), +(2556,'Celaya','MEX',382140), +(2557,'Mazatlán','MEX',380265), +(2558,'Ensenada','MEX',369573), +(2559,'Ahome','MEX',358663), +(2560,'Cajeme','MEX',355679), +(2561,'Cuernavaca','MEX',337966), +(2562,'Tonalá','MEX',336109), +(2563,'Valle de Chalco Solidaridad','MEX',323113), +(2564,'Nuevo Laredo','MEX',310277), +(2565,'Tepic','MEX',305025), +(2566,'Tampico','MEX',294789), +(2567,'Ixtapaluca','MEX',293160), +(2568,'Apodaca','MEX',282941), +(2569,'Guasave','MEX',277201), +(2570,'Gómez Palacio','MEX',272806), +(2571,'Tapachula','MEX',271141), +(2572,'Nicolás Romero','MEX',269393), +(2573,'Coatzacoalcos','MEX',267037), +(2574,'Uruapan','MEX',265211), +(2575,'Victoria','MEX',262686), +(2576,'Oaxaca de Juárez','MEX',256848), +(2577,'Coacalco de Berriozábal','MEX',252270), +(2578,'Pachuca de Soto','MEX',244688), +(2579,'General Escobedo','MEX',232961), +(2580,'Salamanca','MEX',226864), +(2581,'Santa Catarina','MEX',226573), +(2582,'Tehuacán','MEX',225943), +(2583,'Chalco','MEX',222201), +(2584,'Cárdenas','MEX',216903), +(2585,'Campeche','MEX',216735), +(2586,'La Paz','MEX',213045), +(2587,'Othón P. Blanco (Chetumal)','MEX',208014), +(2588,'Texcoco','MEX',203681), +(2589,'La Paz','MEX',196708), +(2590,'Metepec','MEX',194265), +(2591,'Monclova','MEX',193657), +(2592,'Huixquilucan','MEX',193156), +(2593,'Chilpancingo de los Bravo','MEX',192509), +(2594,'Puerto Vallarta','MEX',183741), +(2595,'Fresnillo','MEX',182744), +(2596,'Ciudad Madero','MEX',182012), +(2597,'Soledad de Graciano Sánchez','MEX',179956), +(2598,'San Juan del Río','MEX',179300), +(2599,'San Felipe del Progreso','MEX',177330), +(2600,'Córdoba','MEX',176952); +INSERT INTO City VALUES +(2601,'Tecámac','MEX',172410), +(2602,'Ocosingo','MEX',171495), +(2603,'Carmen','MEX',171367), +(2604,'Lázaro Cárdenas','MEX',170878), +(2605,'Jiutepec','MEX',170428), +(2606,'Papantla','MEX',170123), +(2607,'Comalcalco','MEX',164640), +(2608,'Zamora','MEX',161191), +(2609,'Nogales','MEX',159103), +(2610,'Huimanguillo','MEX',158335), +(2611,'Cuautla','MEX',153132), +(2612,'Minatitlán','MEX',152983), +(2613,'Poza Rica de Hidalgo','MEX',152678), +(2614,'Ciudad Valles','MEX',146411), +(2615,'Navolato','MEX',145396), +(2616,'San Luis Río Colorado','MEX',145276), +(2617,'Pénjamo','MEX',143927), +(2618,'San Andrés Tuxtla','MEX',142251), +(2619,'Guanajuato','MEX',141215), +(2620,'Navojoa','MEX',140495), +(2621,'Zitácuaro','MEX',137970), +(2622,'Boca del Río','MEX',135721), +(2623,'Allende','MEX',134645), +(2624,'Silao','MEX',134037), +(2625,'Macuspana','MEX',133795), +(2626,'San Juan Bautista Tuxtepec','MEX',133675), +(2627,'San Cristóbal de las Casas','MEX',132317), +(2628,'Valle de Santiago','MEX',130557), +(2629,'Guaymas','MEX',130108), +(2630,'Colima','MEX',129454), +(2631,'Dolores Hidalgo','MEX',128675), +(2632,'Lagos de Moreno','MEX',127949), +(2633,'Piedras Negras','MEX',127898), +(2634,'Altamira','MEX',127490), +(2635,'Túxpam','MEX',126475), +(2636,'San Pedro Garza García','MEX',126147), +(2637,'Cuauhtémoc','MEX',124279), +(2638,'Manzanillo','MEX',124014), +(2639,'Iguala de la Independencia','MEX',123883), +(2640,'Zacatecas','MEX',123700), +(2641,'Tlajomulco de Zúñiga','MEX',123220), +(2642,'Tulancingo de Bravo','MEX',121946), +(2643,'Zinacantepec','MEX',121715), +(2644,'San Martín Texmelucan','MEX',121093), +(2645,'Tepatitlán de Morelos','MEX',118948), +(2646,'Martínez de la Torre','MEX',118815), +(2647,'Orizaba','MEX',118488), +(2648,'Apatzingán','MEX',117849), +(2649,'Atlixco','MEX',117019), +(2650,'Delicias','MEX',116132), +(2651,'Ixtlahuaca','MEX',115548), +(2652,'El Mante','MEX',112453), +(2653,'Lerdo','MEX',112272), +(2654,'Almoloya de Juárez','MEX',110550), +(2655,'Acámbaro','MEX',110487), +(2656,'Acuña','MEX',110388), +(2657,'Guadalupe','MEX',108881), +(2658,'Huejutla de Reyes','MEX',108017), +(2659,'Hidalgo','MEX',106198), +(2660,'Los Cabos','MEX',105199), +(2661,'Comitán de Domínguez','MEX',104986), +(2662,'Cunduacán','MEX',104164), +(2663,'Río Bravo','MEX',103901), +(2664,'Temapache','MEX',102824), +(2665,'Chilapa de Alvarez','MEX',102716), +(2666,'Hidalgo del Parral','MEX',100881), +(2667,'San Francisco del Rincón','MEX',100149), +(2668,'Taxco de Alarcón','MEX',99907), +(2669,'Zumpango','MEX',99781), +(2670,'San Pedro Cholula','MEX',99734), +(2671,'Lerma','MEX',99714), +(2672,'Tecomán','MEX',99296), +(2673,'Las Margaritas','MEX',97389), +(2674,'Cosoleacaque','MEX',97199), +(2675,'San Luis de la Paz','MEX',96763), +(2676,'José Azueta','MEX',95448), +(2677,'Santiago Ixcuintla','MEX',95311), +(2678,'San Felipe','MEX',95305), +(2679,'Tejupilco','MEX',94934), +(2680,'Tantoyuca','MEX',94709), +(2681,'Salvatierra','MEX',94322), +(2682,'Tultepec','MEX',93364), +(2683,'Temixco','MEX',92686), +(2684,'Matamoros','MEX',91858), +(2685,'Pánuco','MEX',90551), +(2686,'El Fuerte','MEX',89556), +(2687,'Tierra Blanca','MEX',89143), +(2688,'Weno','FSM',22000), +(2689,'Palikir','FSM',8600), +(2690,'Chisinau','MDA',719900), +(2691,'Tiraspol','MDA',194300), +(2692,'Balti','MDA',153400), +(2693,'Bender (Tîghina)','MDA',125700), +(2694,'Monte-Carlo','MCO',13154), +(2695,'Monaco-Ville','MCO',1234), +(2696,'Ulan Bator','MNG',773700), +(2697,'Plymouth','MSR',2000), +(2698,'Maputo','MOZ',1018938), +(2699,'Matola','MOZ',424662), +(2700,'Beira','MOZ',397368), +(2701,'Nampula','MOZ',303346), +(2702,'Chimoio','MOZ',171056), +(2703,'Naçala-Porto','MOZ',158248), +(2704,'Quelimane','MOZ',150116), +(2705,'Mocuba','MOZ',124700), +(2706,'Tete','MOZ',101984), +(2707,'Xai-Xai','MOZ',99442), +(2708,'Gurue','MOZ',99300), +(2709,'Maxixe','MOZ',93985), +(2710,'Rangoon (Yangon)','MMR',3361700), +(2711,'Mandalay','MMR',885300), +(2712,'Moulmein (Mawlamyine)','MMR',307900), +(2713,'Pegu (Bago)','MMR',190900), +(2714,'Bassein (Pathein)','MMR',183900), +(2715,'Monywa','MMR',138600), +(2716,'Sittwe (Akyab)','MMR',137600), +(2717,'Taunggyi (Taunggye)','MMR',131500), +(2718,'Meikhtila','MMR',129700), +(2719,'Mergui (Myeik)','MMR',122700), +(2720,'Lashio (Lasho)','MMR',107600), +(2721,'Prome (Pyay)','MMR',105700), +(2722,'Henzada (Hinthada)','MMR',104700), +(2723,'Myingyan','MMR',103600), +(2724,'Tavoy (Dawei)','MMR',96800), +(2725,'Pagakku (Pakokku)','MMR',94800), +(2726,'Windhoek','NAM',169000), +(2727,'Yangor','NRU',4050), +(2728,'Yaren','NRU',559), +(2729,'Kathmandu','NPL',591835), +(2730,'Biratnagar','NPL',157764), +(2731,'Pokhara','NPL',146318), +(2732,'Lalitapur','NPL',145847), +(2733,'Birgunj','NPL',90639), +(2734,'Managua','NIC',959000), +(2735,'León','NIC',123865), +(2736,'Chinandega','NIC',97387), +(2737,'Masaya','NIC',88971), +(2738,'Niamey','NER',420000), +(2739,'Zinder','NER',120892), +(2740,'Maradi','NER',112965), +(2741,'Lagos','NGA',1518000), +(2742,'Ibadan','NGA',1432000), +(2743,'Ogbomosho','NGA',730000), +(2744,'Kano','NGA',674100), +(2745,'Oshogbo','NGA',476800), +(2746,'Ilorin','NGA',475800), +(2747,'Abeokuta','NGA',427400), +(2748,'Port Harcourt','NGA',410000), +(2749,'Zaria','NGA',379200), +(2750,'Ilesha','NGA',378400), +(2751,'Onitsha','NGA',371900), +(2752,'Iwo','NGA',362000), +(2753,'Ado-Ekiti','NGA',359400), +(2754,'Abuja','NGA',350100), +(2755,'Kaduna','NGA',342200), +(2756,'Mushin','NGA',333200), +(2757,'Maiduguri','NGA',320000), +(2758,'Enugu','NGA',316100), +(2759,'Ede','NGA',307100), +(2760,'Aba','NGA',298900), +(2761,'Ife','NGA',296800), +(2762,'Ila','NGA',264000), +(2763,'Oyo','NGA',256400), +(2764,'Ikerre','NGA',244600), +(2765,'Benin City','NGA',229400), +(2766,'Iseyin','NGA',217300), +(2767,'Katsina','NGA',206500), +(2768,'Jos','NGA',206300), +(2769,'Sokoto','NGA',204900), +(2770,'Ilobu','NGA',199000), +(2771,'Offa','NGA',197200), +(2772,'Ikorodu','NGA',184900), +(2773,'Ilawe-Ekiti','NGA',184500), +(2774,'Owo','NGA',183500), +(2775,'Ikirun','NGA',181400), +(2776,'Shaki','NGA',174500), +(2777,'Calabar','NGA',174400), +(2778,'Ondo','NGA',173600), +(2779,'Akure','NGA',162300), +(2780,'Gusau','NGA',158000), +(2781,'Ijebu-Ode','NGA',156400), +(2782,'Effon-Alaiye','NGA',153100), +(2783,'Kumo','NGA',148000), +(2784,'Shomolu','NGA',147700), +(2785,'Oka-Akoko','NGA',142900), +(2786,'Ikare','NGA',140800), +(2787,'Sapele','NGA',139200), +(2788,'Deba Habe','NGA',138600), +(2789,'Minna','NGA',136900), +(2790,'Warri','NGA',126100), +(2791,'Bida','NGA',125500), +(2792,'Ikire','NGA',123300), +(2793,'Makurdi','NGA',123100), +(2794,'Lafia','NGA',122500), +(2795,'Inisa','NGA',119800), +(2796,'Shagamu','NGA',117200), +(2797,'Awka','NGA',111200), +(2798,'Gombe','NGA',107800), +(2799,'Igboho','NGA',106800), +(2800,'Ejigbo','NGA',105900); +INSERT INTO City VALUES +(2801,'Agege','NGA',105000), +(2802,'Ise-Ekiti','NGA',103400), +(2803,'Ugep','NGA',102600), +(2804,'Epe','NGA',101000), +(2805,'Alofi','NIU',682), +(2806,'Kingston','NFK',800), +(2807,'Oslo','NOR',508726), +(2808,'Bergen','NOR',230948), +(2809,'Trondheim','NOR',150166), +(2810,'Stavanger','NOR',108848), +(2811,'Bærum','NOR',101340), +(2812,'Abidjan','CIV',2500000), +(2813,'Bouaké','CIV',329850), +(2814,'Yamoussoukro','CIV',130000), +(2815,'Daloa','CIV',121842), +(2816,'Korhogo','CIV',109445), +(2817,'al-Sib','OMN',155000), +(2818,'Salala','OMN',131813), +(2819,'Bawshar','OMN',107500), +(2820,'Suhar','OMN',90814), +(2821,'Masqat','OMN',51969), +(2822,'Karachi','PAK',9269265), +(2823,'Lahore','PAK',5063499), +(2824,'Faisalabad','PAK',1977246), +(2825,'Rawalpindi','PAK',1406214), +(2826,'Multan','PAK',1182441), +(2827,'Hyderabad','PAK',1151274), +(2828,'Gujranwala','PAK',1124749), +(2829,'Peshawar','PAK',988005), +(2830,'Quetta','PAK',560307), +(2831,'Islamabad','PAK',524500), +(2832,'Sargodha','PAK',455360), +(2833,'Sialkot','PAK',417597), +(2834,'Bahawalpur','PAK',403408), +(2835,'Sukkur','PAK',329176), +(2836,'Jhang','PAK',292214), +(2837,'Sheikhupura','PAK',271875), +(2838,'Larkana','PAK',270366), +(2839,'Gujrat','PAK',250121), +(2840,'Mardan','PAK',244511), +(2841,'Kasur','PAK',241649), +(2842,'Rahim Yar Khan','PAK',228479), +(2843,'Sahiwal','PAK',207388), +(2844,'Okara','PAK',200901), +(2845,'Wah','PAK',198400), +(2846,'Dera Ghazi Khan','PAK',188100), +(2847,'Mirpur Khas','PAK',184500), +(2848,'Nawabshah','PAK',183100), +(2849,'Mingora','PAK',174500), +(2850,'Chiniot','PAK',169300), +(2851,'Kamoke','PAK',151000), +(2852,'Mandi Burewala','PAK',149900), +(2853,'Jhelum','PAK',145800), +(2854,'Sadiqabad','PAK',141500), +(2855,'Jacobabad','PAK',137700), +(2856,'Shikarpur','PAK',133300), +(2857,'Khanewal','PAK',133000), +(2858,'Hafizabad','PAK',130200), +(2859,'Kohat','PAK',125300), +(2860,'Muzaffargarh','PAK',121600), +(2861,'Khanpur','PAK',117800), +(2862,'Gojra','PAK',115000), +(2863,'Bahawalnagar','PAK',109600), +(2864,'Muridke','PAK',108600), +(2865,'Pak Pattan','PAK',107800), +(2866,'Abottabad','PAK',106000), +(2867,'Tando Adam','PAK',103400), +(2868,'Jaranwala','PAK',103300), +(2869,'Khairpur','PAK',102200), +(2870,'Chishtian Mandi','PAK',101700), +(2871,'Daska','PAK',101500), +(2872,'Dadu','PAK',98600), +(2873,'Mandi Bahauddin','PAK',97300), +(2874,'Ahmadpur East','PAK',96000), +(2875,'Kamalia','PAK',95300), +(2876,'Khuzdar','PAK',93100), +(2877,'Vihari','PAK',92300), +(2878,'Dera Ismail Khan','PAK',90400), +(2879,'Wazirabad','PAK',89700), +(2880,'Nowshera','PAK',89400), +(2881,'Koror','PLW',12000), +(2882,'Ciudad de Panamá','PAN',471373), +(2883,'San Miguelito','PAN',315382), +(2884,'Port Moresby','PNG',247000), +(2885,'Asunción','PRY',557776), +(2886,'Ciudad del Este','PRY',133881), +(2887,'San Lorenzo','PRY',133395), +(2888,'Lambaré','PRY',99681), +(2889,'Fernando de la Mora','PRY',95287), +(2890,'Lima','PER',6464693), +(2891,'Arequipa','PER',762000), +(2892,'Trujillo','PER',652000), +(2893,'Chiclayo','PER',517000), +(2894,'Callao','PER',424294), +(2895,'Iquitos','PER',367000), +(2896,'Chimbote','PER',336000), +(2897,'Huancayo','PER',327000), +(2898,'Piura','PER',325000), +(2899,'Cusco','PER',291000), +(2900,'Pucallpa','PER',220866), +(2901,'Tacna','PER',215683), +(2902,'Ica','PER',194820), +(2903,'Sullana','PER',147361), +(2904,'Juliaca','PER',142576), +(2905,'Huánuco','PER',129688), +(2906,'Ayacucho','PER',118960), +(2907,'Chincha Alta','PER',110016), +(2908,'Cajamarca','PER',108009), +(2909,'Puno','PER',101578), +(2910,'Ventanilla','PER',101056), +(2911,'Castilla','PER',90642), +(2912,'Adamstown','PCN',42), +(2913,'Garapan','MNP',9200), +(2914,'Lisboa','PRT',563210), +(2915,'Porto','PRT',273060), +(2916,'Amadora','PRT',122106), +(2917,'Coímbra','PRT',96100), +(2918,'Braga','PRT',90535), +(2919,'San Juan','PRI',434374), +(2920,'Bayamón','PRI',224044), +(2921,'Ponce','PRI',186475), +(2922,'Carolina','PRI',186076), +(2923,'Caguas','PRI',140502), +(2924,'Arecibo','PRI',100131), +(2925,'Guaynabo','PRI',100053), +(2926,'Mayagüez','PRI',98434), +(2927,'Toa Baja','PRI',94085), +(2928,'Warszawa','POL',1615369), +(2929,'Lódz','POL',800110), +(2930,'Kraków','POL',738150), +(2931,'Wroclaw','POL',636765), +(2932,'Poznan','POL',576899), +(2933,'Gdansk','POL',458988), +(2934,'Szczecin','POL',416988), +(2935,'Bydgoszcz','POL',386855), +(2936,'Lublin','POL',356251), +(2937,'Katowice','POL',345934), +(2938,'Bialystok','POL',283937), +(2939,'Czestochowa','POL',257812), +(2940,'Gdynia','POL',253521), +(2941,'Sosnowiec','POL',244102), +(2942,'Radom','POL',232262), +(2943,'Kielce','POL',212383), +(2944,'Gliwice','POL',212164), +(2945,'Torun','POL',206158), +(2946,'Bytom','POL',205560), +(2947,'Zabrze','POL',200177), +(2948,'Bielsko-Biala','POL',180307), +(2949,'Olsztyn','POL',170904), +(2950,'Rzeszów','POL',162049), +(2951,'Ruda Slaska','POL',159665), +(2952,'Rybnik','POL',144582), +(2953,'Walbrzych','POL',136923), +(2954,'Tychy','POL',133178), +(2955,'Dabrowa Górnicza','POL',131037), +(2956,'Plock','POL',131011), +(2957,'Elblag','POL',129782), +(2958,'Opole','POL',129553), +(2959,'Gorzów Wielkopolski','POL',126019), +(2960,'Wloclawek','POL',123373), +(2961,'Chorzów','POL',121708), +(2962,'Tarnów','POL',121494), +(2963,'Zielona Góra','POL',118182), +(2964,'Koszalin','POL',112375), +(2965,'Legnica','POL',109335), +(2966,'Kalisz','POL',106641), +(2967,'Grudziadz','POL',102434), +(2968,'Slupsk','POL',102370), +(2969,'Jastrzebie-Zdrój','POL',102294), +(2970,'Jaworzno','POL',97929), +(2971,'Jelenia Góra','POL',93901), +(2972,'Malabo','GNQ',40000), +(2973,'Doha','QAT',355000), +(2974,'Paris','FRA',2125246), +(2975,'Marseille','FRA',798430), +(2976,'Lyon','FRA',445452), +(2977,'Toulouse','FRA',390350), +(2978,'Nice','FRA',342738), +(2979,'Nantes','FRA',270251), +(2980,'Strasbourg','FRA',264115), +(2981,'Montpellier','FRA',225392), +(2982,'Bordeaux','FRA',215363), +(2983,'Rennes','FRA',206229), +(2984,'Le Havre','FRA',190905), +(2985,'Reims','FRA',187206), +(2986,'Lille','FRA',184657), +(2987,'St-Étienne','FRA',180210), +(2988,'Toulon','FRA',160639), +(2989,'Grenoble','FRA',153317), +(2990,'Angers','FRA',151279), +(2991,'Dijon','FRA',149867), +(2992,'Brest','FRA',149634), +(2993,'Le Mans','FRA',146105), +(2994,'Clermont-Ferrand','FRA',137140), +(2995,'Amiens','FRA',135501), +(2996,'Aix-en-Provence','FRA',134222), +(2997,'Limoges','FRA',133968), +(2998,'Nîmes','FRA',133424), +(2999,'Tours','FRA',132820), +(3000,'Villeurbanne','FRA',124215); +INSERT INTO City VALUES +(3001,'Metz','FRA',123776), +(3002,'Besançon','FRA',117733), +(3003,'Caen','FRA',113987), +(3004,'Orléans','FRA',113126), +(3005,'Mulhouse','FRA',110359), +(3006,'Rouen','FRA',106592), +(3007,'Boulogne-Billancourt','FRA',106367), +(3008,'Perpignan','FRA',105115), +(3009,'Nancy','FRA',103605), +(3010,'Roubaix','FRA',96984), +(3011,'Argenteuil','FRA',93961), +(3012,'Tourcoing','FRA',93540), +(3013,'Montreuil','FRA',90674), +(3014,'Cayenne','GUF',50699), +(3015,'Faaa','PYF',25888), +(3016,'Papeete','PYF',25553), +(3017,'Saint-Denis','REU',131480), +(3018,'Bucuresti','ROM',2016131), +(3019,'Iasi','ROM',348070), +(3020,'Constanta','ROM',342264), +(3021,'Cluj-Napoca','ROM',332498), +(3022,'Galati','ROM',330276), +(3023,'Timisoara','ROM',324304), +(3024,'Brasov','ROM',314225), +(3025,'Craiova','ROM',313530), +(3026,'Ploiesti','ROM',251348), +(3027,'Braila','ROM',233756), +(3028,'Oradea','ROM',222239), +(3029,'Bacau','ROM',209235), +(3030,'Pitesti','ROM',187170), +(3031,'Arad','ROM',184408), +(3032,'Sibiu','ROM',169611), +(3033,'Târgu Mures','ROM',165153), +(3034,'Baia Mare','ROM',149665), +(3035,'Buzau','ROM',148372), +(3036,'Satu Mare','ROM',130059), +(3037,'Botosani','ROM',128730), +(3038,'Piatra Neamt','ROM',125070), +(3039,'Râmnicu Vâlcea','ROM',119741), +(3040,'Suceava','ROM',118549), +(3041,'Drobeta-Turnu Severin','ROM',117865), +(3042,'Târgoviste','ROM',98980), +(3043,'Focsani','ROM',98979), +(3044,'Târgu Jiu','ROM',98524), +(3045,'Tulcea','ROM',96278), +(3046,'Resita','ROM',93976), +(3047,'Kigali','RWA',286000), +(3048,'Stockholm','SWE',750348), +(3049,'Gothenburg [Göteborg]','SWE',466990), +(3050,'Malmö','SWE',259579), +(3051,'Uppsala','SWE',189569), +(3052,'Linköping','SWE',133168), +(3053,'Västerås','SWE',126328), +(3054,'Örebro','SWE',124207), +(3055,'Norrköping','SWE',122199), +(3056,'Helsingborg','SWE',117737), +(3057,'Jönköping','SWE',117095), +(3058,'Umeå','SWE',104512), +(3059,'Lund','SWE',98948), +(3060,'Borås','SWE',96883), +(3061,'Sundsvall','SWE',93126), +(3062,'Gävle','SWE',90742), +(3063,'Jamestown','SHN',1500), +(3064,'Basseterre','KNA',11600), +(3065,'Castries','LCA',2301), +(3066,'Kingstown','VCT',17100), +(3067,'Saint-Pierre','SPM',5808), +(3068,'Berlin','DEU',3386667), +(3069,'Hamburg','DEU',1704735), +(3070,'Munich [München]','DEU',1194560), +(3071,'Köln','DEU',962507), +(3072,'Frankfurt am Main','DEU',643821), +(3073,'Essen','DEU',599515), +(3074,'Dortmund','DEU',590213), +(3075,'Stuttgart','DEU',582443), +(3076,'Düsseldorf','DEU',568855), +(3077,'Bremen','DEU',540330), +(3078,'Duisburg','DEU',519793), +(3079,'Hannover','DEU',514718), +(3080,'Leipzig','DEU',489532), +(3081,'Nürnberg','DEU',486628), +(3082,'Dresden','DEU',476668), +(3083,'Bochum','DEU',392830), +(3084,'Wuppertal','DEU',368993), +(3085,'Bielefeld','DEU',321125), +(3086,'Mannheim','DEU',307730), +(3087,'Bonn','DEU',301048), +(3088,'Gelsenkirchen','DEU',281979), +(3089,'Karlsruhe','DEU',277204), +(3090,'Wiesbaden','DEU',268716), +(3091,'Münster','DEU',264670), +(3092,'Mönchengladbach','DEU',263697), +(3093,'Chemnitz','DEU',263222), +(3094,'Augsburg','DEU',254867), +(3095,'Halle/Saale','DEU',254360), +(3096,'Braunschweig','DEU',246322), +(3097,'Aachen','DEU',243825), +(3098,'Krefeld','DEU',241769), +(3099,'Magdeburg','DEU',235073), +(3100,'Kiel','DEU',233795), +(3101,'Oberhausen','DEU',222349), +(3102,'Lübeck','DEU',213326), +(3103,'Hagen','DEU',205201), +(3104,'Rostock','DEU',203279), +(3105,'Freiburg im Breisgau','DEU',202455), +(3106,'Erfurt','DEU',201267), +(3107,'Kassel','DEU',196211), +(3108,'Saarbrücken','DEU',183836), +(3109,'Mainz','DEU',183134), +(3110,'Hamm','DEU',181804), +(3111,'Herne','DEU',175661), +(3112,'Mülheim an der Ruhr','DEU',173895), +(3113,'Solingen','DEU',165583), +(3114,'Osnabrück','DEU',164539), +(3115,'Ludwigshafen am Rhein','DEU',163771), +(3116,'Leverkusen','DEU',160841), +(3117,'Oldenburg','DEU',154125), +(3118,'Neuss','DEU',149702), +(3119,'Heidelberg','DEU',139672), +(3120,'Darmstadt','DEU',137776), +(3121,'Paderborn','DEU',137647), +(3122,'Potsdam','DEU',128983), +(3123,'Würzburg','DEU',127350), +(3124,'Regensburg','DEU',125236), +(3125,'Recklinghausen','DEU',125022), +(3126,'Göttingen','DEU',124775), +(3127,'Bremerhaven','DEU',122735), +(3128,'Wolfsburg','DEU',121954), +(3129,'Bottrop','DEU',121097), +(3130,'Remscheid','DEU',120125), +(3131,'Heilbronn','DEU',119526), +(3132,'Pforzheim','DEU',117227), +(3133,'Offenbach am Main','DEU',116627), +(3134,'Ulm','DEU',116103), +(3135,'Ingolstadt','DEU',114826), +(3136,'Gera','DEU',114718), +(3137,'Salzgitter','DEU',112934), +(3138,'Cottbus','DEU',110894), +(3139,'Reutlingen','DEU',110343), +(3140,'Fürth','DEU',109771), +(3141,'Siegen','DEU',109225), +(3142,'Koblenz','DEU',108003), +(3143,'Moers','DEU',106837), +(3144,'Bergisch Gladbach','DEU',106150), +(3145,'Zwickau','DEU',104146), +(3146,'Hildesheim','DEU',104013), +(3147,'Witten','DEU',103384), +(3148,'Schwerin','DEU',102878), +(3149,'Erlangen','DEU',100750), +(3150,'Kaiserslautern','DEU',100025), +(3151,'Trier','DEU',99891), +(3152,'Jena','DEU',99779), +(3153,'Iserlohn','DEU',99474), +(3154,'Gütersloh','DEU',95028), +(3155,'Marl','DEU',93735), +(3156,'Lünen','DEU',92044), +(3157,'Düren','DEU',91092), +(3158,'Ratingen','DEU',90951), +(3159,'Velbert','DEU',89881), +(3160,'Esslingen am Neckar','DEU',89667), +(3161,'Honiara','SLB',50100), +(3162,'Lusaka','ZMB',1317000), +(3163,'Ndola','ZMB',329200), +(3164,'Kitwe','ZMB',288600), +(3165,'Kabwe','ZMB',154300), +(3166,'Chingola','ZMB',142400), +(3167,'Mufulira','ZMB',123900), +(3168,'Luanshya','ZMB',118100), +(3169,'Apia','WSM',35900), +(3170,'Serravalle','SMR',4802), +(3171,'San Marino','SMR',2294), +(3172,'São Tomé','STP',49541), +(3173,'Riyadh','SAU',3324000), +(3174,'Jedda','SAU',2046300), +(3175,'Mekka','SAU',965700), +(3176,'Medina','SAU',608300), +(3177,'al-Dammam','SAU',482300), +(3178,'al-Taif','SAU',416100), +(3179,'Tabuk','SAU',292600), +(3180,'Burayda','SAU',248600), +(3181,'al-Hufuf','SAU',225800), +(3182,'al-Mubarraz','SAU',219100), +(3183,'Khamis Mushayt','SAU',217900), +(3184,'Hail','SAU',176800), +(3185,'al-Kharj','SAU',152100), +(3186,'al-Khubar','SAU',141700), +(3187,'Jubayl','SAU',140800), +(3188,'Hafar al-Batin','SAU',137800), +(3189,'al-Tuqba','SAU',125700), +(3190,'Yanbu','SAU',119800), +(3191,'Abha','SAU',112300), +(3192,'Ara´ar','SAU',108100), +(3193,'al-Qatif','SAU',98900), +(3194,'al-Hawiya','SAU',93900), +(3195,'Unayza','SAU',91100), +(3196,'Najran','SAU',91000), +(3197,'Pikine','SEN',855287), +(3198,'Dakar','SEN',785071), +(3199,'Thiès','SEN',248000), +(3200,'Kaolack','SEN',199000); +INSERT INTO City VALUES +(3201,'Ziguinchor','SEN',192000), +(3202,'Rufisque','SEN',150000), +(3203,'Saint-Louis','SEN',132400), +(3204,'Mbour','SEN',109300), +(3205,'Diourbel','SEN',99400), +(3206,'Victoria','SYC',41000), +(3207,'Freetown','SLE',850000), +(3208,'Singapore','SGP',4017733), +(3209,'Bratislava','SVK',448292), +(3210,'Košice','SVK',241874), +(3211,'Prešov','SVK',93977), +(3212,'Ljubljana','SVN',270986), +(3213,'Maribor','SVN',115532), +(3214,'Mogadishu','SOM',997000), +(3215,'Hargeysa','SOM',90000), +(3216,'Kismaayo','SOM',90000), +(3217,'Colombo','LKA',645000), +(3218,'Dehiwala','LKA',203000), +(3219,'Moratuwa','LKA',190000), +(3220,'Jaffna','LKA',149000), +(3221,'Kandy','LKA',140000), +(3222,'Sri Jayawardenepura Kotte','LKA',118000), +(3223,'Negombo','LKA',100000), +(3224,'Omdurman','SDN',1271403), +(3225,'Khartum','SDN',947483), +(3226,'Sharq al-Nil','SDN',700887), +(3227,'Port Sudan','SDN',308195), +(3228,'Kassala','SDN',234622), +(3229,'Obeid','SDN',229425), +(3230,'Nyala','SDN',227183), +(3231,'Wad Madani','SDN',211362), +(3232,'al-Qadarif','SDN',191164), +(3233,'Kusti','SDN',173599), +(3234,'al-Fashir','SDN',141884), +(3235,'Juba','SDN',114980), +(3236,'Helsinki [Helsingfors]','FIN',555474), +(3237,'Espoo','FIN',213271), +(3238,'Tampere','FIN',195468), +(3239,'Vantaa','FIN',178471), +(3240,'Turku [Åbo]','FIN',172561), +(3241,'Oulu','FIN',120753), +(3242,'Lahti','FIN',96921), +(3243,'Paramaribo','SUR',112000), +(3244,'Mbabane','SWZ',61000), +(3245,'Zürich','CHE',336800), +(3246,'Geneve','CHE',173500), +(3247,'Basel','CHE',166700), +(3248,'Bern','CHE',122700), +(3249,'Lausanne','CHE',114500), +(3250,'Damascus','SYR',1347000), +(3251,'Aleppo','SYR',1261983), +(3252,'Hims','SYR',507404), +(3253,'Hama','SYR',343361), +(3254,'Latakia','SYR',264563), +(3255,'al-Qamishliya','SYR',144286), +(3256,'Dayr al-Zawr','SYR',140459), +(3257,'Jaramana','SYR',138469), +(3258,'Duma','SYR',131158), +(3259,'al-Raqqa','SYR',108020), +(3260,'Idlib','SYR',91081), +(3261,'Dushanbe','TJK',524000), +(3262,'Khujand','TJK',161500), +(3263,'Taipei','TWN',2641312), +(3264,'Kaohsiung','TWN',1475505), +(3265,'Taichung','TWN',940589), +(3266,'Tainan','TWN',728060), +(3267,'Panchiao','TWN',523850), +(3268,'Chungho','TWN',392176), +(3269,'Keelung (Chilung)','TWN',385201), +(3270,'Sanchung','TWN',380084), +(3271,'Hsinchuang','TWN',365048), +(3272,'Hsinchu','TWN',361958), +(3273,'Chungli','TWN',318649), +(3274,'Fengshan','TWN',318562), +(3275,'Taoyuan','TWN',316438), +(3276,'Chiayi','TWN',265109), +(3277,'Hsintien','TWN',263603), +(3278,'Changhwa','TWN',227715), +(3279,'Yungho','TWN',227700), +(3280,'Tucheng','TWN',224897), +(3281,'Pingtung','TWN',214727), +(3282,'Yungkang','TWN',193005), +(3283,'Pingchen','TWN',188344), +(3284,'Tali','TWN',171940), +(3285,'Taiping','TWN',165524), +(3286,'Pate','TWN',161700), +(3287,'Fengyuan','TWN',161032), +(3288,'Luchou','TWN',160516), +(3289,'Hsichuh','TWN',154976), +(3290,'Shulin','TWN',151260), +(3291,'Yuanlin','TWN',126402), +(3292,'Yangmei','TWN',126323), +(3293,'Taliao','TWN',115897), +(3294,'Kueishan','TWN',112195), +(3295,'Tanshui','TWN',111882), +(3296,'Taitung','TWN',111039), +(3297,'Hualien','TWN',108407), +(3298,'Nantou','TWN',104723), +(3299,'Lungtan','TWN',103088), +(3300,'Touliu','TWN',98900), +(3301,'Tsaotun','TWN',96800), +(3302,'Kangshan','TWN',92200), +(3303,'Ilan','TWN',92000), +(3304,'Miaoli','TWN',90000), +(3305,'Dar es Salaam','TZA',1747000), +(3306,'Dodoma','TZA',189000), +(3307,'Mwanza','TZA',172300), +(3308,'Zanzibar','TZA',157634), +(3309,'Tanga','TZA',137400), +(3310,'Mbeya','TZA',130800), +(3311,'Morogoro','TZA',117800), +(3312,'Arusha','TZA',102500), +(3313,'Moshi','TZA',96800), +(3314,'Tabora','TZA',92800), +(3315,'København','DNK',495699), +(3316,'Århus','DNK',284846), +(3317,'Odense','DNK',183912), +(3318,'Aalborg','DNK',161161), +(3319,'Frederiksberg','DNK',90327), +(3320,'Bangkok','THA',6320174), +(3321,'Nonthaburi','THA',292100), +(3322,'Nakhon Ratchasima','THA',181400), +(3323,'Chiang Mai','THA',171100), +(3324,'Udon Thani','THA',158100), +(3325,'Hat Yai','THA',148632), +(3326,'Khon Kaen','THA',126500), +(3327,'Pak Kret','THA',126055), +(3328,'Nakhon Sawan','THA',123800), +(3329,'Ubon Ratchathani','THA',116300), +(3330,'Songkhla','THA',94900), +(3331,'Nakhon Pathom','THA',94100), +(3332,'Lomé','TGO',375000), +(3333,'Fakaofo','TKL',300), +(3334,'Nuku´alofa','TON',22400), +(3335,'Chaguanas','TTO',56601), +(3336,'Port-of-Spain','TTO',43396), +(3337,'N´Djaména','TCD',530965), +(3338,'Moundou','TCD',99500), +(3339,'Praha','CZE',1181126), +(3340,'Brno','CZE',381862), +(3341,'Ostrava','CZE',320041), +(3342,'Plzen','CZE',166759), +(3343,'Olomouc','CZE',102702), +(3344,'Liberec','CZE',99155), +(3345,'Ceské Budejovice','CZE',98186), +(3346,'Hradec Králové','CZE',98080), +(3347,'Ústí nad Labem','CZE',95491), +(3348,'Pardubice','CZE',91309), +(3349,'Tunis','TUN',690600), +(3350,'Sfax','TUN',257800), +(3351,'Ariana','TUN',197000), +(3352,'Ettadhamen','TUN',178600), +(3353,'Sousse','TUN',145900), +(3354,'Kairouan','TUN',113100), +(3355,'Biserta','TUN',108900), +(3356,'Gabès','TUN',106600), +(3357,'Istanbul','TUR',8787958), +(3358,'Ankara','TUR',3038159), +(3359,'Izmir','TUR',2130359), +(3360,'Adana','TUR',1131198), +(3361,'Bursa','TUR',1095842), +(3362,'Gaziantep','TUR',789056), +(3363,'Konya','TUR',628364), +(3364,'Mersin (Içel)','TUR',587212), +(3365,'Antalya','TUR',564914), +(3366,'Diyarbakir','TUR',479884), +(3367,'Kayseri','TUR',475657), +(3368,'Eskisehir','TUR',470781), +(3369,'Sanliurfa','TUR',405905), +(3370,'Samsun','TUR',339871), +(3371,'Malatya','TUR',330312), +(3372,'Gebze','TUR',264170), +(3373,'Denizli','TUR',253848), +(3374,'Sivas','TUR',246642), +(3375,'Erzurum','TUR',246535), +(3376,'Tarsus','TUR',246206), +(3377,'Kahramanmaras','TUR',245772), +(3378,'Elâzig','TUR',228815), +(3379,'Van','TUR',219319), +(3380,'Sultanbeyli','TUR',211068), +(3381,'Izmit (Kocaeli)','TUR',210068), +(3382,'Manisa','TUR',207148), +(3383,'Batman','TUR',203793), +(3384,'Balikesir','TUR',196382), +(3385,'Sakarya (Adapazari)','TUR',190641), +(3386,'Iskenderun','TUR',153022), +(3387,'Osmaniye','TUR',146003), +(3388,'Çorum','TUR',145495), +(3389,'Kütahya','TUR',144761), +(3390,'Hatay (Antakya)','TUR',143982), +(3391,'Kirikkale','TUR',142044), +(3392,'Adiyaman','TUR',141529), +(3393,'Trabzon','TUR',138234), +(3394,'Ordu','TUR',133642), +(3395,'Aydin','TUR',128651), +(3396,'Usak','TUR',128162), +(3397,'Edirne','TUR',123383), +(3398,'Çorlu','TUR',123300), +(3399,'Isparta','TUR',121911), +(3400,'Karabük','TUR',118285); +INSERT INTO City VALUES +(3401,'Kilis','TUR',118245), +(3402,'Alanya','TUR',117300), +(3403,'Kiziltepe','TUR',112000), +(3404,'Zonguldak','TUR',111542), +(3405,'Siirt','TUR',107100), +(3406,'Viransehir','TUR',106400), +(3407,'Tekirdag','TUR',106077), +(3408,'Karaman','TUR',104200), +(3409,'Afyon','TUR',103984), +(3410,'Aksaray','TUR',102681), +(3411,'Ceyhan','TUR',102412), +(3412,'Erzincan','TUR',102304), +(3413,'Bismil','TUR',101400), +(3414,'Nazilli','TUR',99900), +(3415,'Tokat','TUR',99500), +(3416,'Kars','TUR',93000), +(3417,'Inegöl','TUR',90500), +(3418,'Bandirma','TUR',90200), +(3419,'Ashgabat','TKM',540600), +(3420,'Chärjew','TKM',189200), +(3421,'Dashhowuz','TKM',141800), +(3422,'Mary','TKM',101000), +(3423,'Cockburn Town','TCA',4800), +(3424,'Funafuti','TUV',4600), +(3425,'Kampala','UGA',890800), +(3426,'Kyiv','UKR',2624000), +(3427,'Harkova [Harkiv]','UKR',1500000), +(3428,'Dnipropetrovsk','UKR',1103000), +(3429,'Donetsk','UKR',1050000), +(3430,'Odesa','UKR',1011000), +(3431,'Zaporizzja','UKR',848000), +(3432,'Lviv','UKR',788000), +(3433,'Kryvyi Rig','UKR',703000), +(3434,'Mykolajiv','UKR',508000), +(3435,'Mariupol','UKR',490000), +(3436,'Lugansk','UKR',469000), +(3437,'Vinnytsja','UKR',391000), +(3438,'Makijivka','UKR',384000), +(3439,'Herson','UKR',353000), +(3440,'Sevastopol','UKR',348000), +(3441,'Simferopol','UKR',339000), +(3442,'Pultava [Poltava]','UKR',313000), +(3443,'Tšernigiv','UKR',313000), +(3444,'Tšerkasy','UKR',309000), +(3445,'Gorlivka','UKR',299000), +(3446,'Zytomyr','UKR',297000), +(3447,'Sumy','UKR',294000), +(3448,'Dniprodzerzynsk','UKR',270000), +(3449,'Kirovograd','UKR',265000), +(3450,'Hmelnytskyi','UKR',262000), +(3451,'Tšernivtsi','UKR',259000), +(3452,'Rivne','UKR',245000), +(3453,'Krementšuk','UKR',239000), +(3454,'Ivano-Frankivsk','UKR',237000), +(3455,'Ternopil','UKR',236000), +(3456,'Lutsk','UKR',217000), +(3457,'Bila Tserkva','UKR',215000), +(3458,'Kramatorsk','UKR',186000), +(3459,'Melitopol','UKR',169000), +(3460,'Kertš','UKR',162000), +(3461,'Nikopol','UKR',149000), +(3462,'Berdjansk','UKR',130000), +(3463,'Pavlograd','UKR',127000), +(3464,'Sjeverodonetsk','UKR',127000), +(3465,'Slovjansk','UKR',127000), +(3466,'Uzgorod','UKR',127000), +(3467,'Altševsk','UKR',119000), +(3468,'Lysytšansk','UKR',116000), +(3469,'Jevpatorija','UKR',112000), +(3470,'Kamjanets-Podilskyi','UKR',109000), +(3471,'Jenakijeve','UKR',105000), +(3472,'Krasnyi Lutš','UKR',101000), +(3473,'Stahanov','UKR',101000), +(3474,'Oleksandrija','UKR',99000), +(3475,'Konotop','UKR',96000), +(3476,'Kostjantynivka','UKR',95000), +(3477,'Berdytšiv','UKR',90000), +(3478,'Izmajil','UKR',90000), +(3479,'Šostka','UKR',90000), +(3480,'Uman','UKR',90000), +(3481,'Brovary','UKR',89000), +(3482,'Mukatševe','UKR',89000), +(3483,'Budapest','HUN',1811552), +(3484,'Debrecen','HUN',203648), +(3485,'Miskolc','HUN',172357), +(3486,'Szeged','HUN',158158), +(3487,'Pécs','HUN',157332), +(3488,'Györ','HUN',127119), +(3489,'Nyiregyháza','HUN',112419), +(3490,'Kecskemét','HUN',105606), +(3491,'Székesfehérvár','HUN',105119), +(3492,'Montevideo','URY',1236000), +(3493,'Nouméa','NCL',76293), +(3494,'Auckland','NZL',381800), +(3495,'Christchurch','NZL',324200), +(3496,'Manukau','NZL',281800), +(3497,'North Shore','NZL',187700), +(3498,'Waitakere','NZL',170600), +(3499,'Wellington','NZL',166700), +(3500,'Dunedin','NZL',119600), +(3501,'Hamilton','NZL',117100), +(3502,'Lower Hutt','NZL',98100), +(3503,'Toskent','UZB',2117500), +(3504,'Namangan','UZB',370500), +(3505,'Samarkand','UZB',361800), +(3506,'Andijon','UZB',318600), +(3507,'Buhoro','UZB',237100), +(3508,'Karsi','UZB',194100), +(3509,'Nukus','UZB',194100), +(3510,'Kükon','UZB',190100), +(3511,'Fargona','UZB',180500), +(3512,'Circik','UZB',146400), +(3513,'Margilon','UZB',140800), +(3514,'Ürgenc','UZB',138900), +(3515,'Angren','UZB',128000), +(3516,'Cizah','UZB',124800), +(3517,'Navoi','UZB',116300), +(3518,'Olmalik','UZB',114900), +(3519,'Termiz','UZB',109500), +(3520,'Minsk','BLR',1674000), +(3521,'Gomel','BLR',475000), +(3522,'Mogiljov','BLR',356000), +(3523,'Vitebsk','BLR',340000), +(3524,'Grodno','BLR',302000), +(3525,'Brest','BLR',286000), +(3526,'Bobruisk','BLR',221000), +(3527,'Baranovitši','BLR',167000), +(3528,'Borisov','BLR',151000), +(3529,'Pinsk','BLR',130000), +(3530,'Orša','BLR',124000), +(3531,'Mozyr','BLR',110000), +(3532,'Novopolotsk','BLR',106000), +(3533,'Lida','BLR',101000), +(3534,'Soligorsk','BLR',101000), +(3535,'Molodetšno','BLR',97000), +(3536,'Mata-Utu','WLF',1137), +(3537,'Port-Vila','VUT',33700), +(3538,'Città del Vaticano','VAT',455), +(3539,'Caracas','VEN',1975294), +(3540,'Maracaíbo','VEN',1304776), +(3541,'Barquisimeto','VEN',877239), +(3542,'Valencia','VEN',794246), +(3543,'Ciudad Guayana','VEN',663713), +(3544,'Petare','VEN',488868), +(3545,'Maracay','VEN',444443), +(3546,'Barcelona','VEN',322267), +(3547,'Maturín','VEN',319726), +(3548,'San Cristóbal','VEN',319373), +(3549,'Ciudad Bolívar','VEN',301107), +(3550,'Cumaná','VEN',293105), +(3551,'Mérida','VEN',224887), +(3552,'Cabimas','VEN',221329), +(3553,'Barinas','VEN',217831), +(3554,'Turmero','VEN',217499), +(3555,'Baruta','VEN',207290), +(3556,'Puerto Cabello','VEN',187722), +(3557,'Santa Ana de Coro','VEN',185766), +(3558,'Los Teques','VEN',178784), +(3559,'Punto Fijo','VEN',167215), +(3560,'Guarenas','VEN',165889), +(3561,'Acarigua','VEN',158954), +(3562,'Puerto La Cruz','VEN',155700), +(3563,'Ciudad Losada','VEN',134501), +(3564,'Guacara','VEN',131334), +(3565,'Valera','VEN',130281), +(3566,'Guanare','VEN',125621), +(3567,'Carúpano','VEN',119639), +(3568,'Catia La Mar','VEN',117012), +(3569,'El Tigre','VEN',116256), +(3570,'Guatire','VEN',109121), +(3571,'Calabozo','VEN',107146), +(3572,'Pozuelos','VEN',105690), +(3573,'Ciudad Ojeda','VEN',99354), +(3574,'Ocumare del Tuy','VEN',97168), +(3575,'Valle de la Pascua','VEN',95927), +(3576,'Araure','VEN',94269), +(3577,'San Fernando de Apure','VEN',93809), +(3578,'San Felipe','VEN',90940), +(3579,'El Limón','VEN',90000), +(3580,'Moscow','RUS',8389200), +(3581,'St Petersburg','RUS',4694000), +(3582,'Novosibirsk','RUS',1398800), +(3583,'Nizni Novgorod','RUS',1357000), +(3584,'Jekaterinburg','RUS',1266300), +(3585,'Samara','RUS',1156100), +(3586,'Omsk','RUS',1148900), +(3587,'Kazan','RUS',1101000), +(3588,'Ufa','RUS',1091200), +(3589,'Tšeljabinsk','RUS',1083200), +(3590,'Rostov-na-Donu','RUS',1012700), +(3591,'Perm','RUS',1009700), +(3592,'Volgograd','RUS',993400), +(3593,'Voronez','RUS',907700), +(3594,'Krasnojarsk','RUS',875500), +(3595,'Saratov','RUS',874000), +(3596,'Toljatti','RUS',722900), +(3597,'Uljanovsk','RUS',667400), +(3598,'Izevsk','RUS',652800), +(3599,'Krasnodar','RUS',639000), +(3600,'Jaroslavl','RUS',616700); +INSERT INTO City VALUES +(3601,'Habarovsk','RUS',609400), +(3602,'Vladivostok','RUS',606200), +(3603,'Irkutsk','RUS',593700), +(3604,'Barnaul','RUS',580100), +(3605,'Novokuznetsk','RUS',561600), +(3606,'Penza','RUS',532200), +(3607,'Rjazan','RUS',529900), +(3608,'Orenburg','RUS',523600), +(3609,'Lipetsk','RUS',521000), +(3610,'Nabereznyje Tšelny','RUS',514700), +(3611,'Tula','RUS',506100), +(3612,'Tjumen','RUS',503400), +(3613,'Kemerovo','RUS',492700), +(3614,'Astrahan','RUS',486100), +(3615,'Tomsk','RUS',482100), +(3616,'Kirov','RUS',466200), +(3617,'Ivanovo','RUS',459200), +(3618,'Tšeboksary','RUS',459200), +(3619,'Brjansk','RUS',457400), +(3620,'Tver','RUS',454900), +(3621,'Kursk','RUS',443500), +(3622,'Magnitogorsk','RUS',427900), +(3623,'Kaliningrad','RUS',424400), +(3624,'Nizni Tagil','RUS',390900), +(3625,'Murmansk','RUS',376300), +(3626,'Ulan-Ude','RUS',370400), +(3627,'Kurgan','RUS',364700), +(3628,'Arkangeli','RUS',361800), +(3629,'Sotši','RUS',358600), +(3630,'Smolensk','RUS',353400), +(3631,'Orjol','RUS',344500), +(3632,'Stavropol','RUS',343300), +(3633,'Belgorod','RUS',342000), +(3634,'Kaluga','RUS',339300), +(3635,'Vladimir','RUS',337100), +(3636,'Mahatškala','RUS',332800), +(3637,'Tšerepovets','RUS',324400), +(3638,'Saransk','RUS',314800), +(3639,'Tambov','RUS',312000), +(3640,'Vladikavkaz','RUS',310100), +(3641,'Tšita','RUS',309900), +(3642,'Vologda','RUS',302500), +(3643,'Veliki Novgorod','RUS',299500), +(3644,'Komsomolsk-na-Amure','RUS',291600), +(3645,'Kostroma','RUS',288100), +(3646,'Volzski','RUS',286900), +(3647,'Taganrog','RUS',284400), +(3648,'Petroskoi','RUS',282100), +(3649,'Bratsk','RUS',277600), +(3650,'Dzerzinsk','RUS',277100), +(3651,'Surgut','RUS',274900), +(3652,'Orsk','RUS',273900), +(3653,'Sterlitamak','RUS',265200), +(3654,'Angarsk','RUS',264700), +(3655,'Joškar-Ola','RUS',249200), +(3656,'Rybinsk','RUS',239600), +(3657,'Prokopjevsk','RUS',237300), +(3658,'Niznevartovsk','RUS',233900), +(3659,'Naltšik','RUS',233400), +(3660,'Syktyvkar','RUS',229700), +(3661,'Severodvinsk','RUS',229300), +(3662,'Bijsk','RUS',225000), +(3663,'Niznekamsk','RUS',223400), +(3664,'Blagoveštšensk','RUS',222000), +(3665,'Šahty','RUS',221800), +(3666,'Staryi Oskol','RUS',213800), +(3667,'Zelenograd','RUS',207100), +(3668,'Balakovo','RUS',206000), +(3669,'Novorossijsk','RUS',203300), +(3670,'Pihkova','RUS',201500), +(3671,'Zlatoust','RUS',196900), +(3672,'Jakutsk','RUS',195400), +(3673,'Podolsk','RUS',194300), +(3674,'Petropavlovsk-Kamtšatski','RUS',194100), +(3675,'Kamensk-Uralski','RUS',190600), +(3676,'Engels','RUS',189000), +(3677,'Syzran','RUS',186900), +(3678,'Grozny','RUS',186000), +(3679,'Novotšerkassk','RUS',184400), +(3680,'Berezniki','RUS',181900), +(3681,'Juzno-Sahalinsk','RUS',179200), +(3682,'Volgodonsk','RUS',178200), +(3683,'Abakan','RUS',169200), +(3684,'Maikop','RUS',167300), +(3685,'Miass','RUS',166200), +(3686,'Armavir','RUS',164900), +(3687,'Ljubertsy','RUS',163900), +(3688,'Rubtsovsk','RUS',162600), +(3689,'Kovrov','RUS',159900), +(3690,'Nahodka','RUS',157700), +(3691,'Ussurijsk','RUS',157300), +(3692,'Salavat','RUS',156800), +(3693,'Mytištši','RUS',155700), +(3694,'Kolomna','RUS',150700), +(3695,'Elektrostal','RUS',147000), +(3696,'Murom','RUS',142400), +(3697,'Kolpino','RUS',141200), +(3698,'Norilsk','RUS',140800), +(3699,'Almetjevsk','RUS',140700), +(3700,'Novomoskovsk','RUS',138100), +(3701,'Dimitrovgrad','RUS',137000), +(3702,'Pervouralsk','RUS',136100), +(3703,'Himki','RUS',133700), +(3704,'Balašiha','RUS',132900), +(3705,'Nevinnomyssk','RUS',132600), +(3706,'Pjatigorsk','RUS',132500), +(3707,'Korolev','RUS',132400), +(3708,'Serpuhov','RUS',132000), +(3709,'Odintsovo','RUS',127400), +(3710,'Orehovo-Zujevo','RUS',124900), +(3711,'Kamyšin','RUS',124600), +(3712,'Novotšeboksarsk','RUS',123400), +(3713,'Tšerkessk','RUS',121700), +(3714,'Atšinsk','RUS',121600), +(3715,'Magadan','RUS',121000), +(3716,'Mitšurinsk','RUS',120700), +(3717,'Kislovodsk','RUS',120400), +(3718,'Jelets','RUS',119400), +(3719,'Seversk','RUS',118600), +(3720,'Noginsk','RUS',117200), +(3721,'Velikije Luki','RUS',116300), +(3722,'Novokuibyševsk','RUS',116200), +(3723,'Neftekamsk','RUS',115700), +(3724,'Leninsk-Kuznetski','RUS',113800), +(3725,'Oktjabrski','RUS',111500), +(3726,'Sergijev Posad','RUS',111100), +(3727,'Arzamas','RUS',110700), +(3728,'Kiseljovsk','RUS',110000), +(3729,'Novotroitsk','RUS',109600), +(3730,'Obninsk','RUS',108300), +(3731,'Kansk','RUS',107400), +(3732,'Glazov','RUS',106300), +(3733,'Solikamsk','RUS',106000), +(3734,'Sarapul','RUS',105700), +(3735,'Ust-Ilimsk','RUS',105200), +(3736,'Štšolkovo','RUS',104900), +(3737,'Mezduretšensk','RUS',104400), +(3738,'Usolje-Sibirskoje','RUS',103500), +(3739,'Elista','RUS',103300), +(3740,'Novošahtinsk','RUS',101900), +(3741,'Votkinsk','RUS',101700), +(3742,'Kyzyl','RUS',101100), +(3743,'Serov','RUS',100400), +(3744,'Zelenodolsk','RUS',100200), +(3745,'Zeleznodoroznyi','RUS',100100), +(3746,'Kinešma','RUS',100000), +(3747,'Kuznetsk','RUS',98200), +(3748,'Uhta','RUS',98000), +(3749,'Jessentuki','RUS',97900), +(3750,'Tobolsk','RUS',97600), +(3751,'Neftejugansk','RUS',97400), +(3752,'Bataisk','RUS',97300), +(3753,'Nojabrsk','RUS',97300), +(3754,'Balašov','RUS',97100), +(3755,'Zeleznogorsk','RUS',96900), +(3756,'Zukovski','RUS',96500), +(3757,'Anzero-Sudzensk','RUS',96100), +(3758,'Bugulma','RUS',94100), +(3759,'Zeleznogorsk','RUS',94000), +(3760,'Novouralsk','RUS',93300), +(3761,'Puškin','RUS',92900), +(3762,'Vorkuta','RUS',92600), +(3763,'Derbent','RUS',92300), +(3764,'Kirovo-Tšepetsk','RUS',91600), +(3765,'Krasnogorsk','RUS',91000), +(3766,'Klin','RUS',90000), +(3767,'Tšaikovski','RUS',90000), +(3768,'Novyi Urengoi','RUS',89800), +(3769,'Ho Chi Minh City','VNM',3980000), +(3770,'Hanoi','VNM',1410000), +(3771,'Haiphong','VNM',783133), +(3772,'Da Nang','VNM',382674), +(3773,'Biên Hoa','VNM',282095), +(3774,'Nha Trang','VNM',221331), +(3775,'Hue','VNM',219149), +(3776,'Can Tho','VNM',215587), +(3777,'Cam Pha','VNM',209086), +(3778,'Nam Dinh','VNM',171699), +(3779,'Quy Nhon','VNM',163385), +(3780,'Vung Tau','VNM',145145), +(3781,'Rach Gia','VNM',141132), +(3782,'Long Xuyen','VNM',132681), +(3783,'Thai Nguyen','VNM',127643), +(3784,'Hong Gai','VNM',127484), +(3785,'Phan Thiêt','VNM',114236), +(3786,'Cam Ranh','VNM',114041), +(3787,'Vinh','VNM',112455), +(3788,'My Tho','VNM',108404), +(3789,'Da Lat','VNM',106409), +(3790,'Buon Ma Thuot','VNM',97044), +(3791,'Tallinn','EST',403981), +(3792,'Tartu','EST',101246), +(3793,'New York','USA',8008278), +(3794,'Los Angeles','USA',3694820), +(3795,'Chicago','USA',2896016), +(3796,'Houston','USA',1953631), +(3797,'Philadelphia','USA',1517550), +(3798,'Phoenix','USA',1321045), +(3799,'San Diego','USA',1223400), +(3800,'Dallas','USA',1188580); +INSERT INTO City VALUES +(3801,'San Antonio','USA',1144646), +(3802,'Detroit','USA',951270), +(3803,'San Jose','USA',894943), +(3804,'Indianapolis','USA',791926), +(3805,'San Francisco','USA',776733), +(3806,'Jacksonville','USA',735167), +(3807,'Columbus','USA',711470), +(3808,'Austin','USA',656562), +(3809,'Baltimore','USA',651154), +(3810,'Memphis','USA',650100), +(3811,'Milwaukee','USA',596974), +(3812,'Boston','USA',589141), +(3813,'Washington','USA',572059), +(3814,'Nashville-Davidson','USA',569891), +(3815,'El Paso','USA',563662), +(3816,'Seattle','USA',563374), +(3817,'Denver','USA',554636), +(3818,'Charlotte','USA',540828), +(3819,'Fort Worth','USA',534694), +(3820,'Portland','USA',529121), +(3821,'Oklahoma City','USA',506132), +(3822,'Tucson','USA',486699), +(3823,'New Orleans','USA',484674), +(3824,'Las Vegas','USA',478434), +(3825,'Cleveland','USA',478403), +(3826,'Long Beach','USA',461522), +(3827,'Albuquerque','USA',448607), +(3828,'Kansas City','USA',441545), +(3829,'Fresno','USA',427652), +(3830,'Virginia Beach','USA',425257), +(3831,'Atlanta','USA',416474), +(3832,'Sacramento','USA',407018), +(3833,'Oakland','USA',399484), +(3834,'Mesa','USA',396375), +(3835,'Tulsa','USA',393049), +(3836,'Omaha','USA',390007), +(3837,'Minneapolis','USA',382618), +(3838,'Honolulu','USA',371657), +(3839,'Miami','USA',362470), +(3840,'Colorado Springs','USA',360890), +(3841,'Saint Louis','USA',348189), +(3842,'Wichita','USA',344284), +(3843,'Santa Ana','USA',337977), +(3844,'Pittsburgh','USA',334563), +(3845,'Arlington','USA',332969), +(3846,'Cincinnati','USA',331285), +(3847,'Anaheim','USA',328014), +(3848,'Toledo','USA',313619), +(3849,'Tampa','USA',303447), +(3850,'Buffalo','USA',292648), +(3851,'Saint Paul','USA',287151), +(3852,'Corpus Christi','USA',277454), +(3853,'Aurora','USA',276393), +(3854,'Raleigh','USA',276093), +(3855,'Newark','USA',273546), +(3856,'Lexington-Fayette','USA',260512), +(3857,'Anchorage','USA',260283), +(3858,'Louisville','USA',256231), +(3859,'Riverside','USA',255166), +(3860,'Saint Petersburg','USA',248232), +(3861,'Bakersfield','USA',247057), +(3862,'Stockton','USA',243771), +(3863,'Birmingham','USA',242820), +(3864,'Jersey City','USA',240055), +(3865,'Norfolk','USA',234403), +(3866,'Baton Rouge','USA',227818), +(3867,'Hialeah','USA',226419), +(3868,'Lincoln','USA',225581), +(3869,'Greensboro','USA',223891), +(3870,'Plano','USA',222030), +(3871,'Rochester','USA',219773), +(3872,'Glendale','USA',218812), +(3873,'Akron','USA',217074), +(3874,'Garland','USA',215768), +(3875,'Madison','USA',208054), +(3876,'Fort Wayne','USA',205727), +(3877,'Fremont','USA',203413), +(3878,'Scottsdale','USA',202705), +(3879,'Montgomery','USA',201568), +(3880,'Shreveport','USA',200145), +(3881,'Augusta-Richmond County','USA',199775), +(3882,'Lubbock','USA',199564), +(3883,'Chesapeake','USA',199184), +(3884,'Mobile','USA',198915), +(3885,'Des Moines','USA',198682), +(3886,'Grand Rapids','USA',197800), +(3887,'Richmond','USA',197790), +(3888,'Yonkers','USA',196086), +(3889,'Spokane','USA',195629), +(3890,'Glendale','USA',194973), +(3891,'Tacoma','USA',193556), +(3892,'Irving','USA',191615), +(3893,'Huntington Beach','USA',189594), +(3894,'Modesto','USA',188856), +(3895,'Durham','USA',187035), +(3896,'Columbus','USA',186291), +(3897,'Orlando','USA',185951), +(3898,'Boise City','USA',185787), +(3899,'Winston-Salem','USA',185776), +(3900,'San Bernardino','USA',185401), +(3901,'Jackson','USA',184256), +(3902,'Little Rock','USA',183133), +(3903,'Salt Lake City','USA',181743), +(3904,'Reno','USA',180480), +(3905,'Newport News','USA',180150), +(3906,'Chandler','USA',176581), +(3907,'Laredo','USA',176576), +(3908,'Henderson','USA',175381), +(3909,'Arlington','USA',174838), +(3910,'Knoxville','USA',173890), +(3911,'Amarillo','USA',173627), +(3912,'Providence','USA',173618), +(3913,'Chula Vista','USA',173556), +(3914,'Worcester','USA',172648), +(3915,'Oxnard','USA',170358), +(3916,'Dayton','USA',166179), +(3917,'Garden Grove','USA',165196), +(3918,'Oceanside','USA',161029), +(3919,'Tempe','USA',158625), +(3920,'Huntsville','USA',158216), +(3921,'Ontario','USA',158007), +(3922,'Chattanooga','USA',155554), +(3923,'Fort Lauderdale','USA',152397), +(3924,'Springfield','USA',152082), +(3925,'Springfield','USA',151580), +(3926,'Santa Clarita','USA',151088), +(3927,'Salinas','USA',151060), +(3928,'Tallahassee','USA',150624), +(3929,'Rockford','USA',150115), +(3930,'Pomona','USA',149473), +(3931,'Metairie','USA',149428), +(3932,'Paterson','USA',149222), +(3933,'Overland Park','USA',149080), +(3934,'Santa Rosa','USA',147595), +(3935,'Syracuse','USA',147306), +(3936,'Kansas City','USA',146866), +(3937,'Hampton','USA',146437), +(3938,'Lakewood','USA',144126), +(3939,'Vancouver','USA',143560), +(3940,'Irvine','USA',143072), +(3941,'Aurora','USA',142990), +(3942,'Moreno Valley','USA',142381), +(3943,'Pasadena','USA',141674), +(3944,'Hayward','USA',140030), +(3945,'Brownsville','USA',139722), +(3946,'Bridgeport','USA',139529), +(3947,'Hollywood','USA',139357), +(3948,'Warren','USA',138247), +(3949,'Torrance','USA',137946), +(3950,'Eugene','USA',137893), +(3951,'Pembroke Pines','USA',137427), +(3952,'Salem','USA',136924), +(3953,'Pasadena','USA',133936), +(3954,'Escondido','USA',133559), +(3955,'Sunnyvale','USA',131760), +(3956,'Savannah','USA',131510), +(3957,'Fontana','USA',128929), +(3958,'Orange','USA',128821), +(3959,'Naperville','USA',128358), +(3960,'Alexandria','USA',128283), +(3961,'Rancho Cucamonga','USA',127743), +(3962,'Grand Prairie','USA',127427), +(3963,'East Los Angeles','USA',126379), +(3964,'Fullerton','USA',126003), +(3965,'Corona','USA',124966), +(3966,'Flint','USA',124943), +(3967,'Paradise','USA',124682), +(3968,'Mesquite','USA',124523), +(3969,'Sterling Heights','USA',124471), +(3970,'Sioux Falls','USA',123975), +(3971,'New Haven','USA',123626), +(3972,'Topeka','USA',122377), +(3973,'Concord','USA',121780), +(3974,'Evansville','USA',121582), +(3975,'Hartford','USA',121578), +(3976,'Fayetteville','USA',121015), +(3977,'Cedar Rapids','USA',120758), +(3978,'Elizabeth','USA',120568), +(3979,'Lansing','USA',119128), +(3980,'Lancaster','USA',118718), +(3981,'Fort Collins','USA',118652), +(3982,'Coral Springs','USA',117549), +(3983,'Stamford','USA',117083), +(3984,'Thousand Oaks','USA',117005), +(3985,'Vallejo','USA',116760), +(3986,'Palmdale','USA',116670), +(3987,'Columbia','USA',116278), +(3988,'El Monte','USA',115965), +(3989,'Abilene','USA',115930), +(3990,'North Las Vegas','USA',115488), +(3991,'Ann Arbor','USA',114024), +(3992,'Beaumont','USA',113866), +(3993,'Waco','USA',113726), +(3994,'Macon','USA',113336), +(3995,'Independence','USA',113288), +(3996,'Peoria','USA',112936), +(3997,'Inglewood','USA',112580), +(3998,'Springfield','USA',111454), +(3999,'Simi Valley','USA',111351), +(4000,'Lafayette','USA',110257); +INSERT INTO City VALUES +(4001,'Gilbert','USA',109697), +(4002,'Carrollton','USA',109576), +(4003,'Bellevue','USA',109569), +(4004,'West Valley City','USA',108896), +(4005,'Clarksville','USA',108787), +(4006,'Costa Mesa','USA',108724), +(4007,'Peoria','USA',108364), +(4008,'South Bend','USA',107789), +(4009,'Downey','USA',107323), +(4010,'Waterbury','USA',107271), +(4011,'Manchester','USA',107006), +(4012,'Allentown','USA',106632), +(4013,'McAllen','USA',106414), +(4014,'Joliet','USA',106221), +(4015,'Lowell','USA',105167), +(4016,'Provo','USA',105166), +(4017,'West Covina','USA',105080), +(4018,'Wichita Falls','USA',104197), +(4019,'Erie','USA',103717), +(4020,'Daly City','USA',103621), +(4021,'Citrus Heights','USA',103455), +(4022,'Norwalk','USA',103298), +(4023,'Gary','USA',102746), +(4024,'Berkeley','USA',102743), +(4025,'Santa Clara','USA',102361), +(4026,'Green Bay','USA',102313), +(4027,'Cape Coral','USA',102286), +(4028,'Arvada','USA',102153), +(4029,'Pueblo','USA',102121), +(4030,'Sandy','USA',101853), +(4031,'Athens-Clarke County','USA',101489), +(4032,'Cambridge','USA',101355), +(4033,'Westminster','USA',100940), +(4034,'San Buenaventura','USA',100916), +(4035,'Portsmouth','USA',100565), +(4036,'Livonia','USA',100545), +(4037,'Burbank','USA',100316), +(4038,'Clearwater','USA',99936), +(4039,'Midland','USA',98293), +(4040,'Davenport','USA',98256), +(4041,'Mission Viejo','USA',98049), +(4042,'Miami Beach','USA',97855), +(4043,'Sunrise Manor','USA',95362), +(4044,'New Bedford','USA',94780), +(4045,'El Cajon','USA',94578), +(4046,'Norman','USA',94193), +(4047,'Richmond','USA',94100), +(4048,'Albany','USA',93994), +(4049,'Brockton','USA',93653), +(4050,'Roanoke','USA',93357), +(4051,'Billings','USA',92988), +(4052,'Compton','USA',92864), +(4053,'Gainesville','USA',92291), +(4054,'Fairfield','USA',92256), +(4055,'Arden-Arcade','USA',92040), +(4056,'San Mateo','USA',91799), +(4057,'Visalia','USA',91762), +(4058,'Boulder','USA',91238), +(4059,'Cary','USA',91213), +(4060,'Santa Monica','USA',91084), +(4061,'Fall River','USA',90555), +(4062,'Kenosha','USA',89447), +(4063,'Elgin','USA',89408), +(4064,'Odessa','USA',89293), +(4065,'Carson','USA',89089), +(4066,'Charleston','USA',89063), +(4067,'Charlotte Amalie','VIR',13000), +(4068,'Harare','ZWE',1410000), +(4069,'Bulawayo','ZWE',621742), +(4070,'Chitungwiza','ZWE',274912), +(4071,'Mount Darwin','ZWE',164362), +(4072,'Mutare','ZWE',131367), +(4073,'Gweru','ZWE',128037), +(4074,'Gaza','PSE',353632), +(4075,'Khan Yunis','PSE',123175), +(4076,'Hebron','PSE',119401), +(4077,'Jabaliya','PSE',113901), +(4078,'Nablus','PSE',100231), +(4079,'Rafah','PSE',92020); + +# Table CountryLanguage + +INSERT INTO CountryLanguage VALUES +('AFG','Pashto',52.4), +('NLD','Dutch',95.6), +('ANT','Papiamento',86.2), +('ALB','Albaniana',97.9), +('DZA','Arabic',86.0), +('ASM','Samoan',90.6), +('AND','Spanish',44.6), +('AGO','Ovimbundu',37.2), +('AIA','English',0.0), +('ATG','Creole English',95.7), +('ARE','Arabic',42.0), +('ARG','Spanish',96.8), +('ARM','Armenian',93.4), +('ABW','Papiamento',76.7), +('AUS','English',81.2), +('AZE','Azerbaijani',89.0), +('BHS','Creole English',89.7), +('BHR','Arabic',67.7), +('BGD','Bengali',97.7), +('BRB','Bajan',95.1), +('BEL','Dutch',59.2), +('BLZ','English',50.8), +('BEN','Fon',39.8), +('BMU','English',100.0), +('BTN','Dzongkha',50.0), +('BOL','Spanish',87.7), +('BIH','Serbo-Croatian',99.2), +('BWA','Tswana',75.5), +('BRA','Portuguese',97.5), +('GBR','English',97.3), +('VGB','English',0.0), +('BRN','Malay',45.5), +('BGR','Bulgariana',83.2), +('BFA','Mossi',50.2), +('BDI','Kirundi',98.1), +('CYM','English',0.0), +('CHL','Spanish',89.7), +('COK','Maori',0.0), +('CRI','Spanish',97.5), +('DJI','Somali',43.9), +('DMA','Creole English',100.0), +('DOM','Spanish',98.0), +('ECU','Spanish',93.0), +('EGY','Arabic',98.8), +('SLV','Spanish',100.0), +('ERI','Tigrinja',49.1), +('ESP','Spanish',74.4), +('ZAF','Zulu',22.7), +('ETH','Oromo',31.0), +('FLK','English',0.0), +('FJI','Fijian',50.8), +('PHL','Pilipino',29.3), +('FRO','Faroese',100.0), +('GAB','Fang',35.8), +('GMB','Malinke',34.1), +('GEO','Georgiana',71.7), +('GHA','Akan',52.4), +('GIB','English',88.9), +('GRD','Creole English',100.0), +('GRL','Greenlandic',87.5), +('GLP','Creole French',95.0), +('GUM','English',37.5), +('GTM','Spanish',64.7), +('GIN','Ful',38.6), +('GNB','Crioulo',36.4), +('GUY','Creole English',96.4), +('HTI','Haiti Creole',100.0), +('HND','Spanish',97.2), +('HKG','Canton Chinese',88.7), +('SJM','Norwegian',0.0), +('IDN','Javanese',39.4), +('IND','Hindi',39.9), +('IRQ','Arabic',77.2), +('IRN','Persian',45.7), +('IRL','English',98.4), +('ISL','Icelandic',95.7), +('ISR','Hebrew',63.1), +('ITA','Italian',94.1), +('TMP','Sunda',0.0), +('AUT','German',92.0), +('JAM','Creole English',94.2), +('JPN','Japanese',99.1), +('YEM','Arabic',99.6), +('JOR','Arabic',97.9), +('CXR','Chinese',0.0), +('YUG','Serbo-Croatian',75.2), +('KHM','Khmer',88.6), +('CMR','Fang',19.7), +('CAN','English',60.4), +('CPV','Crioulo',100.0), +('KAZ','Kazakh',46.0), +('KEN','Kikuyu',20.9), +('CAF','Gbaya',23.8), +('CHN','Chinese',92.0), +('KGZ','Kirgiz',59.7), +('KIR','Kiribati',98.9), +('COL','Spanish',99.0), +('COM','Comorian',75.0), +('COG','Kongo',51.5), +('COD','Luba',18.0), +('CCK','Malay',0.0), +('PRK','Korean',99.9), +('KOR','Korean',99.9), +('GRC','Greek',98.5), +('HRV','Serbo-Croatian',95.9), +('CUB','Spanish',100.0), +('KWT','Arabic',78.1), +('CYP','Greek',74.1), +('LAO','Lao',67.2), +('LVA','Latvian',55.1), +('LSO','Sotho',85.0), +('LBN','Arabic',93.0), +('LBR','Kpelle',19.5), +('LBY','Arabic',96.0), +('LIE','German',89.0), +('LTU','Lithuanian',81.6), +('LUX','Luxembourgish',64.4), +('ESH','Arabic',100.0), +('MAC','Canton Chinese',85.6), +('MDG','Malagasy',98.9), +('MKD','Macedonian',66.5), +('MWI','Chichewa',58.3), +('MDV','Dhivehi',100.0), +('MYS','Malay',58.4), +('MLI','Bambara',31.8), +('MLT','Maltese',95.8), +('MAR','Arabic',65.0), +('MHL','Marshallese',96.8), +('MTQ','Creole French',96.6), +('MRT','Hassaniya',81.7), +('MUS','Creole French',70.6), +('MYT','Mahoré',41.9), +('MEX','Spanish',92.1), +('FSM','Trukese',41.6), +('MDA','Romanian',61.9), +('MCO','French',41.9), +('MNG','Mongolian',78.8), +('MSR','English',0.0), +('MOZ','Makua',27.8), +('MMR','Burmese',69.0), +('NAM','Ovambo',50.7), +('NRU','Nauru',57.5), +('NPL','Nepali',50.4), +('NIC','Spanish',97.6), +('NER','Hausa',53.1), +('NGA','Joruba',21.4), +('NIU','Niue',0.0), +('NFK','English',0.0), +('NOR','Norwegian',96.6), +('CIV','Akan',30.0), +('OMN','Arabic',76.7), +('PAK','Punjabi',48.2), +('PLW','Palau',82.2), +('PAN','Spanish',76.8), +('PNG','Papuan Languages',78.1), +('PRY','Spanish',55.1), +('PER','Spanish',79.8), +('PCN','Pitcairnese',0.0), +('MNP','Philippene Languages',34.1), +('PRT','Portuguese',99.0), +('PRI','Spanish',51.3), +('POL','Polish',97.6), +('GNQ','Fang',84.8), +('QAT','Arabic',40.7), +('FRA','French',93.6), +('GUF','Creole French',94.3), +('PYF','Tahitian',46.4), +('REU','Creole French',91.5), +('ROM','Romanian',90.7), +('RWA','Rwanda',100.0), +('SWE','Swedish',89.5), +('SHN','English',0.0), +('KNA','Creole English',100.0), +('LCA','Creole French',80.0), +('VCT','Creole English',99.1), +('SPM','French',0.0), +('DEU','German',91.3), +('SLB','Malenasian Languages',85.6), +('ZMB','Bemba',29.7), +('WSM','Samoan-English',52.0), +('SMR','Italian',100.0), +('STP','Crioulo',86.3), +('SAU','Arabic',95.0), +('SEN','Wolof',48.1), +('SYC','Seselwa',91.3), +('SLE','Mende',34.8), +('SGP','Chinese',77.1), +('SVK','Slovak',85.6), +('SVN','Slovene',87.9), +('SOM','Somali',98.3), +('LKA','Singali',60.3), +('SDN','Arabic',49.4), +('FIN','Finnish',92.7), +('SUR','Sranantonga',81.0), +('SWZ','Swazi',89.9), +('CHE','German',63.6), +('SYR','Arabic',90.0), +('TJK','Tadzhik',62.2), +('TWN','Min',66.7), +('TZA','Nyamwesi',21.1); +INSERT INTO CountryLanguage VALUES +('DNK','Danish',93.5), +('THA','Thai',52.6), +('TGO','Ewe',23.2), +('TKL','Tokelau',0.0), +('TON','Tongan',98.3), +('TTO','English',93.5), +('TCD','Sara',27.7), +('CZE','Czech',81.2), +('TUN','Arabic',69.9), +('TUR','Turkish',87.6), +('TKM','Turkmenian',76.7), +('TCA','English',0.0), +('TUV','Tuvalu',92.5), +('UGA','Ganda',18.1), +('UKR','Ukrainian',64.7), +('HUN','Hungarian',98.5), +('URY','Spanish',95.7), +('NCL','Malenasian Languages',45.4), +('NZL','English',87.0), +('UZB','Uzbek',72.6), +('BLR','Belorussian',65.6), +('WLF','Wallis',0.0), +('VUT','Bislama',56.6), +('VAT','Italian',0.0), +('VEN','Spanish',96.9), +('RUS','Russian',86.6), +('VNM','Vietnamese',86.8), +('EST','Estonian',65.3), +('USA','English',86.2), +('VIR','English',81.7), +('UMI','English',0.0), +('ZWE','Shona',72.1), +('PSE','Arabic',95.9), +('AFG','Dari',32.1), +('NLD','Fries',3.7), +('ANT','English',7.8), +('ALB','Greek',1.8), +('DZA','Berberi',14.0), +('ASM','English',3.1), +('AND','Catalan',32.3), +('AGO','Mbundu',21.6), +('ATG','English',0.0), +('ARE','Hindi',0.0), +('ARG','Italian',1.7), +('ARM','Azerbaijani',2.6), +('ABW','English',9.5), +('AUS','Italian',2.2), +('AZE','Russian',3.0), +('BHS','Creole French',10.3), +('BHR','English',0.0), +('BGD','Chakma',0.4), +('BRB','English',0.0), +('BEL','French',32.6), +('BLZ','Spanish',31.6), +('BEN','Joruba',12.2), +('BTN','Nepali',34.8), +('BOL','Ketšua',8.1), +('BWA','Shona',12.3), +('BRA','German',0.5), +('GBR','Kymri',0.9), +('BRN','Malay-English',28.8), +('BGR','Turkish',9.4), +('BFA','Ful',9.7), +('BDI','French',0.0), +('CHL','Araucan',9.6), +('COK','English',0.0), +('CRI','Creole English',2.0), +('DJI','Afar',34.8), +('DMA','Creole French',0.0), +('DOM','Creole French',2.0), +('ECU','Ketšua',7.0), +('EGY','Sinaberberi',0.0), +('SLV','Nahua',0.0), +('ERI','Tigre',31.7), +('ESP','Catalan',16.9), +('ZAF','Xhosa',17.7), +('ETH','Amhara',30.0), +('FJI','Hindi',43.7), +('PHL','Cebuano',23.3), +('FRO','Danish',0.0), +('GAB','Punu-sira-nzebi',17.1), +('GMB','Ful',16.2), +('GEO','Russian',8.8), +('GHA','Mossi',15.8), +('GIB','Arabic',7.4), +('GRL','Danish',12.5), +('GLP','French',0.0), +('GUM','Chamorro',29.6), +('GTM','Quiché',10.1), +('GIN','Malinke',23.2), +('GNB','Ful',16.6), +('GUY','Caribbean',2.2), +('HTI','French',0.0), +('HND','Garifuna',1.3), +('HKG','English',2.2), +('SJM','Russian',0.0), +('IDN','Sunda',15.8), +('IND','Bengali',8.2), +('IRQ','Kurdish',19.0), +('IRN','Azerbaijani',16.8), +('IRL','Irish',1.6), +('ISL','English',0.0), +('ISR','Arabic',18.0), +('ITA','Sardinian',2.7), +('TMP','Portuguese',0.0), +('AUT','Serbo-Croatian',2.2), +('JAM','Hindi',1.9), +('JPN','Korean',0.5), +('YEM','Soqutri',0.0), +('JOR','Circassian',1.0), +('CXR','English',0.0), +('YUG','Albaniana',16.5), +('KHM','Vietnamese',5.5), +('CMR','Bamileke-bamum',18.6), +('CAN','French',23.4), +('CPV','Portuguese',0.0), +('KAZ','Russian',34.7), +('KEN','Luhya',13.8), +('CAF','Banda',23.5), +('CHN','Zhuang',1.4), +('KGZ','Russian',16.2), +('KIR','Tuvalu',0.5), +('COL','Chibcha',0.4), +('COM','Comorian-French',12.9), +('COG','Teke',17.3), +('COD','Kongo',16.0), +('CCK','English',0.0), +('PRK','Chinese',0.1), +('KOR','Chinese',0.1), +('GRC','Turkish',0.9), +('HRV','Slovene',0.0), +('KWT','English',0.0), +('CYP','Turkish',22.4), +('LAO','Mon-khmer',16.5), +('LVA','Russian',32.5), +('LSO','Zulu',15.0), +('LBN','Armenian',5.9), +('LBR','Bassa',13.7), +('LBY','Berberi',1.0), +('LIE','Italian',2.5), +('LTU','Russian',8.1), +('LUX','Portuguese',13.0), +('MAC','Portuguese',2.3), +('MDG','French',0.0), +('MKD','Albaniana',22.9), +('MWI','Lomwe',18.4), +('MDV','English',0.0), +('MYS','Chinese',9.0), +('MLI','Ful',13.9), +('MLT','English',2.1), +('MAR','Berberi',33.0), +('MHL','English',0.0), +('MTQ','French',0.0), +('MRT','Wolof',6.6), +('MUS','Bhojpuri',21.1), +('MYT','French',20.3), +('MEX','Náhuatl',1.8), +('FSM','Pohnpei',23.8), +('MDA','Russian',23.2), +('MCO','Monegasque',16.1), +('MNG','Kazakh',5.9), +('MOZ','Tsonga',12.4), +('MMR','Shan',8.5), +('NAM','Nama',12.4), +('NRU','Kiribati',17.9), +('NPL','Maithili',11.9), +('NIC','Miskito',1.6), +('NER','Songhai-zerma',21.2), +('NGA','Hausa',21.1), +('NIU','English',0.0), +('NOR','English',0.5), +('CIV','Gur',11.7), +('OMN','Balochi',0.0), +('PAK','Pashto',13.1), +('PLW','Philippene Languages',9.2), +('PAN','Creole English',14.0), +('PNG','Malenasian Languages',20.0), +('PRY','Guaraní',40.1), +('PER','Ketšua',16.4), +('MNP','Chamorro',30.0), +('PRI','English',47.4), +('POL','German',1.3), +('GNQ','Bubi',8.7), +('QAT','Urdu',0.0), +('FRA','Arabic',2.5), +('GUF','Indian Languages',1.9), +('PYF','French',40.8), +('REU','Chinese',2.8), +('ROM','Hungarian',7.2), +('RWA','French',0.0), +('SWE','Finnish',2.4), +('KNA','English',0.0), +('LCA','English',20.0), +('VCT','English',0.0), +('DEU','Turkish',2.6), +('SLB','Papuan Languages',8.6), +('ZMB','Tongan',11.0), +('WSM','Samoan',47.5), +('STP','French',0.7), +('SEN','Ful',21.7); +INSERT INTO CountryLanguage VALUES +('SYC','English',3.8), +('SLE','Temne',31.8), +('SGP','Malay',14.1), +('SVK','Hungarian',10.5), +('SVN','Serbo-Croatian',7.9), +('SOM','Arabic',0.0), +('LKA','Tamil',19.6), +('SDN','Dinka',11.5), +('FIN','Swedish',5.7), +('SUR','Hindi',0.0), +('SWZ','Zulu',2.0), +('CHE','French',19.2), +('SYR','Kurdish',9.0), +('TJK','Uzbek',23.2), +('TWN','Mandarin Chinese',20.1), +('TZA','Swahili',8.8), +('DNK','Turkish',0.8), +('THA','Lao',26.9), +('TGO','Kabyé',13.8), +('TKL','English',0.0), +('TON','English',0.0), +('TTO','Hindi',3.4), +('TCD','Arabic',12.3), +('CZE','Moravian',12.9), +('TUN','Arabic-French',26.3), +('TUR','Kurdish',10.6), +('TKM','Uzbek',9.2), +('TUV','Kiribati',7.5), +('UGA','Nkole',10.7), +('UKR','Russian',32.9), +('HUN','Romani',0.5), +('NCL','French',34.3), +('NZL','Maori',4.3), +('UZB','Russian',10.9), +('BLR','Russian',32.0), +('WLF','Futuna',0.0), +('VUT','English',28.3), +('VEN','Goajiro',0.4), +('RUS','Tatar',3.2), +('VNM','Tho',1.8), +('EST','Russian',27.8), +('USA','Spanish',7.5), +('VIR','Spanish',13.3), +('ZWE','Ndebele',16.2), +('PSE','Hebrew',4.1), +('AFG','Uzbek',8.8), +('NLD','Arabic',0.9), +('ANT','Dutch',0.0), +('ALB','Macedonian',0.1), +('ASM','Tongan',3.1), +('AND','Portuguese',10.8), +('AGO','Kongo',13.2), +('ARG','Indian Languages',0.3), +('ABW','Spanish',7.4), +('AUS','Greek',1.6), +('AZE','Lezgian',2.3), +('BGD','Marma',0.2), +('BEL','Italian',2.4), +('BLZ','Maya Languages',9.6), +('BEN','Adja',11.1), +('BTN','Asami',15.2), +('BOL','Aimará',3.2), +('BWA','San',3.5), +('BRA','Italian',0.4), +('GBR','Gaeli',0.1), +('BRN','Chinese',9.3), +('BGR','Romani',3.7), +('BFA','Gurma',5.7), +('BDI','Swahili',0.0), +('CHL','Aimará',0.5), +('CRI','Chibcha',0.3), +('DJI','Arabic',10.6), +('ERI','Afar',4.3), +('ESP','Galecian',6.4), +('ZAF','Afrikaans',14.3), +('ETH','Tigrinja',7.2), +('PHL','Ilocano',9.3), +('GAB','Mpongwe',14.6), +('GMB','Wolof',12.6), +('GEO','Armenian',6.8), +('GHA','Ewe',11.9), +('GUM','Philippene Languages',19.7), +('GTM','Cakchiquel',8.9), +('GIN','Susu',11.0), +('GNB','Balante',14.6), +('GUY','Arawakan',1.4), +('HND','Creole English',0.2), +('HKG','Fukien',1.9), +('IDN','Malay',12.1), +('IND','Telugu',7.8), +('IRQ','Azerbaijani',1.7), +('IRN','Kurdish',9.1), +('ISR','Russian',8.9), +('ITA','Friuli',1.2), +('AUT','Turkish',1.5), +('JPN','Chinese',0.2), +('JOR','Armenian',1.0), +('YUG','Hungarian',3.4), +('KHM','Chinese',3.1), +('CMR','Duala',10.9), +('CAN','Chinese',2.5), +('KAZ','Ukrainian',5.0), +('KEN','Luo',12.8), +('CAF','Mandjia',14.8), +('CHN','Mantšu',0.9), +('KGZ','Uzbek',14.1), +('COL','Creole English',0.1), +('COM','Comorian-madagassi',5.5), +('COG','Mboshi',11.4), +('COD','Mongo',13.5), +('LAO','Thai',7.8), +('LVA','Belorussian',4.1), +('LSO','English',0.0), +('LBN','French',0.0), +('LBR','Grebo',8.9), +('LIE','Turkish',2.5), +('LTU','Polish',7.0), +('LUX','Italian',4.6), +('MAC','Mandarin Chinese',1.2), +('MKD','Turkish',4.0), +('MWI','Yao',13.2), +('MYS','Tamil',3.9), +('MLI','Senufo and Minianka',12.0), +('MRT','Tukulor',5.4), +('MUS','French',3.4), +('MYT','Malagasy',16.1), +('MEX','Yucatec',1.1), +('FSM','Mortlock',7.6), +('MDA','Ukrainian',8.6), +('MCO','Italian',16.1), +('MNG','Dorbet',2.7), +('MOZ','Sena',9.4), +('MMR','Karen',6.2), +('NAM','Kavango',9.7), +('NRU','Chinese',8.5), +('NPL','Bhojpuri',7.5), +('NIC','Creole English',0.5), +('NER','Tamashek',10.4), +('NGA','Ibo',18.1), +('NOR','Danish',0.4), +('CIV','Malinke',11.4), +('PAK','Sindhi',11.8), +('PLW','English',3.2), +('PAN','Guaymí',5.3), +('PRY','Portuguese',3.2), +('PER','Aimará',2.3), +('MNP','Chinese',7.1), +('POL','Ukrainian',0.6), +('FRA','Portuguese',1.2), +('PYF','Chinese',2.9), +('REU','Comorian',2.8), +('ROM','Romani',0.7), +('SWE','Southern Slavic Languages',1.3), +('DEU','Southern Slavic Languages',1.4), +('SLB','Polynesian Languages',3.8), +('ZMB','Nyanja',7.8), +('WSM','English',0.6), +('SEN','Serer',12.5), +('SYC','French',1.3), +('SLE','Limba',8.3), +('SGP','Tamil',7.4), +('SVK','Romani',1.7), +('SVN','Hungarian',0.5), +('LKA','Mixed Languages',19.6), +('SDN','Nubian Languages',8.1), +('FIN','Russian',0.4), +('CHE','Italian',7.7), +('TJK','Russian',9.7), +('TWN','Hakka',11.0), +('TZA','Hehet',6.9), +('DNK','Arabic',0.7), +('THA','Chinese',12.1), +('TGO','Watyi',10.3), +('TTO','Creole English',2.9), +('TCD','Mayo-kebbi',11.5), +('CZE','Slovak',3.1), +('TUN','Arabic-French-English',3.2), +('TUR','Arabic',1.4), +('TKM','Russian',6.7), +('TUV','English',0.0), +('UGA','Kiga',8.3), +('UKR','Romanian',0.7), +('HUN','German',0.4), +('NCL','Polynesian Languages',11.6), +('UZB','Tadzhik',4.4), +('BLR','Ukrainian',1.3), +('VUT','French',14.2), +('VEN','Warrau',0.1), +('RUS','Ukrainian',1.3), +('VNM','Thai',1.6), +('EST','Ukrainian',2.8), +('USA','French',0.7), +('VIR','French',2.5), +('ZWE','English',2.2), +('AFG','Turkmenian',1.9), +('NLD','Turkish',0.8), +('AND','French',6.2), +('AGO','Luimbe-nganguela',5.4), +('ABW','Dutch',5.3), +('AUS','Canton Chinese',1.1); +INSERT INTO CountryLanguage VALUES +('AZE','Armenian',2.0), +('BGD','Garo',0.1), +('BEL','Arabic',1.6), +('BLZ','Garifuna',6.8), +('BEN','Aizo',8.7), +('BOL','Guaraní',0.1), +('BWA','Khoekhoe',2.5), +('BRA','Japanese',0.4), +('BRN','English',3.1), +('BGR','Macedonian',2.6), +('BFA','Busansi',3.5), +('CHL','Rapa nui',0.2), +('CRI','Chinese',0.2), +('ERI','Hadareb',3.8), +('ESP','Basque',1.6), +('ZAF','Northsotho',9.1), +('ETH','Gurage',4.7), +('PHL','Hiligaynon',9.1), +('GAB','Mbete',13.8), +('GMB','Diola',9.2), +('GEO','Azerbaijani',5.5), +('GHA','Ga-adangme',7.8), +('GUM','Korean',3.3), +('GTM','Kekchí',4.9), +('GIN','Kissi',6.0), +('GNB','Portuguese',8.1), +('HND','Miskito',0.2), +('HKG','Hakka',1.6), +('IDN','Madura',4.3), +('IND','Marathi',7.4), +('IRQ','Assyrian',0.8), +('IRN','Gilaki',5.3), +('ITA','French',0.5), +('AUT','Hungarian',0.4), +('JPN','English',0.1), +('YUG','Romani',1.4), +('KHM','Tšam',2.4), +('CMR','Ful',9.6), +('CAN','Italian',1.7), +('KAZ','German',3.1), +('KEN','Kamba',11.2), +('CAF','Ngbaka',7.5), +('CHN','Hui',0.8), +('KGZ','Ukrainian',1.7), +('COL','Arawakan',0.1), +('COM','Comorian-Arabic',1.6), +('COG','Mbete',4.8), +('COD','Rwanda',10.3), +('LAO','Lao-Soung',5.2), +('LVA','Ukrainian',2.9), +('LBR','Gio',7.9), +('LTU','Belorussian',1.4), +('LUX','French',4.2), +('MAC','English',0.5), +('MKD','Romani',2.3), +('MWI','Ngoni',6.7), +('MYS','Iban',2.8), +('MLI','Soninke',8.7), +('MRT','Soninke',2.7), +('MUS','Hindi',1.2), +('MEX','Zapotec',0.6), +('FSM','Kosrean',7.3), +('MDA','Gagauzi',3.2), +('MCO','English',6.5), +('MNG','Bajad',1.9), +('MOZ','Lomwe',7.8), +('MMR','Rakhine',4.5), +('NAM','Afrikaans',9.5), +('NRU','Tuvalu',8.5), +('NPL','Tharu',5.4), +('NIC','Sumo',0.2), +('NER','Ful',9.7), +('NGA','Ful',11.3), +('NOR','Swedish',0.3), +('CIV','Kru',10.5), +('PAK','Saraiki',9.8), +('PLW','Chinese',1.6), +('PAN','Cuna',2.0), +('PRY','German',0.9), +('MNP','Korean',6.5), +('POL','Belorussian',0.5), +('FRA','Italian',0.4), +('REU','Malagasy',1.4), +('ROM','German',0.4), +('SWE','Arabic',0.8), +('DEU','Italian',0.7), +('ZMB','Lozi',6.4), +('SEN','Diola',5.0), +('SLE','Kono-vai',5.1), +('SVK','Czech and Moravian',1.1), +('SDN','Beja',6.4), +('FIN','Estonian',0.2), +('CHE','Romansh',0.6), +('TWN','Ami',0.6), +('TZA','Haya',5.9), +('DNK','German',0.5), +('THA','Malay',3.6), +('TGO','Kotokoli',5.7), +('TCD','Kanem-bornu',9.0), +('CZE','Polish',0.6), +('TKM','Kazakh',2.0), +('UGA','Soga',8.2), +('UKR','Bulgariana',0.3), +('HUN','Serbo-Croatian',0.2), +('UZB','Kazakh',3.8), +('BLR','Polish',0.6), +('RUS','Chuvash',0.9), +('VNM','Muong',1.5), +('EST','Belorussian',1.4), +('USA','German',0.7), +('ZWE','Nyanja',2.2), +('AFG','Balochi',0.9), +('AGO','Nyaneka-nkhumbi',5.4), +('AUS','Arabic',1.0), +('BGD','Khasi',0.1), +('BEL','German',1.0), +('BEN','Bariba',8.7), +('BWA','Ndebele',1.3), +('BRA','Indian Languages',0.2), +('BFA','Dagara',3.1), +('ERI','Bilin',3.0), +('ZAF','English',8.5), +('ETH','Somali',4.1), +('PHL','Bicol',5.7), +('GMB','Soninke',7.6), +('GEO','Osseetti',2.4), +('GHA','Gurma',3.3), +('GUM','Japanese',2.0), +('GTM','Mam',2.7), +('GIN','Kpelle',4.6), +('GNB','Malinke',6.9), +('HKG','Chiu chau',1.4), +('IDN','Minangkabau',2.4), +('IND','Tamil',6.3), +('IRQ','Persian',0.8), +('IRN','Luri',4.3), +('ITA','German',0.5), +('AUT','Slovene',0.4), +('JPN','Philippene Languages',0.1), +('YUG','Slovak',0.7), +('CMR','Tikar',7.4), +('CAN','German',1.6), +('KAZ','Uzbek',2.3), +('KEN','Kalenjin',10.8), +('CAF','Sara',6.4), +('CHN','Miao',0.7), +('KGZ','Tatar',1.3), +('COL','Caribbean',0.1), +('COM','Comorian-Swahili',0.5), +('COG','Punu',2.9), +('COD','Zande',6.1), +('LVA','Polish',2.1), +('LBR','Kru',7.2), +('LTU','Ukrainian',1.1), +('LUX','German',2.3), +('MKD','Serbo-Croatian',2.0), +('MYS','English',1.6), +('MLI','Tamashek',7.3), +('MRT','Ful',1.2), +('MUS','Tamil',0.8), +('MEX','Mixtec',0.6), +('FSM','Yap',5.8), +('MDA','Bulgariana',1.6), +('MNG','Buryat',1.7), +('MOZ','Shona',6.5), +('MMR','Mon',2.4), +('NAM','Herero',8.0), +('NRU','English',7.5), +('NPL','Tamang',4.9), +('NER','Kanuri',4.4), +('NGA','Ibibio',5.6), +('NOR','Saame',0.0), +('CIV','[South]Mande',7.7), +('PAK','Urdu',7.6), +('PAN','Embera',0.6), +('MNP','English',4.8), +('FRA','Spanish',0.4), +('REU','Tamil',0.0), +('ROM','Ukrainian',0.3), +('SWE','Spanish',0.6), +('DEU','Greek',0.4), +('ZMB','Chewa',5.7), +('SEN','Malinke',3.8), +('SLE','Bullom-sherbro',3.8), +('SVK','Ukrainian and Russian',0.6), +('SDN','Nuer',4.9), +('FIN','Saame',0.0), +('TWN','Atayal',0.4), +('TZA','Makonde',5.9), +('DNK','English',0.3), +('THA','Khmer',1.3), +('TGO','Ane',5.7), +('TCD','Ouaddai',8.7), +('CZE','German',0.5), +('UGA','Teso',6.0), +('UKR','Hungarian',0.3), +('HUN','Romanian',0.1), +('UZB','Karakalpak',2.0), +('RUS','Bashkir',0.7), +('VNM','Chinese',1.4); +INSERT INTO CountryLanguage VALUES +('EST','Finnish',0.7), +('USA','Italian',0.6), +('AGO','Chokwe',4.2), +('AUS','Vietnamese',0.8), +('BGD','Santhali',0.1), +('BEL','Turkish',0.9), +('BEN','Somba',6.7), +('BFA','Dyula',2.6), +('ERI','Saho',3.0), +('ZAF','Tswana',8.1), +('ETH','Sidamo',3.2), +('PHL','Waray-waray',3.8), +('GEO','Abhyasi',1.7), +('GHA','Joruba',1.3), +('GIN','Yalunka',2.9), +('GNB','Mandyako',4.9), +('IDN','Batakki',2.2), +('IND','Urdu',5.1), +('IRN','Mazandarani',3.6), +('ITA','Albaniana',0.2), +('AUT','Polish',0.2), +('JPN','Ainu',0.0), +('YUG','Macedonian',0.5), +('CMR','Mandara',5.7), +('CAN','Polish',0.7), +('KAZ','Tatar',2.0), +('KEN','Gusii',6.1), +('CAF','Mbum',6.4), +('CHN','Uighur',0.6), +('KGZ','Kazakh',0.8), +('COG','Sango',2.6), +('COD','Ngala and Bangi',5.8), +('LVA','Lithuanian',1.2), +('LBR','Mano',7.2), +('MYS','Dusun',1.1), +('MLI','Songhai',6.9), +('MRT','Zenaga',1.2), +('MUS','Marathi',0.7), +('MEX','Otomí',0.4), +('FSM','Wolea',3.7), +('MNG','Dariganga',1.4), +('MOZ','Tswa',6.0), +('MMR','Chin',2.2), +('NAM','Caprivi',4.7), +('NPL','Newari',3.7), +('NGA','Kanuri',4.1), +('PAK','Balochi',3.0), +('PAN','Arabic',0.6), +('MNP','Carolinian',4.8), +('FRA','Turkish',0.4), +('ROM','Serbo-Croatian',0.1), +('SWE','Norwegian',0.5), +('DEU','Polish',0.3), +('ZMB','Nsenga',4.3), +('SEN','Soninke',1.3), +('SLE','Ful',3.8), +('SDN','Zande',2.7), +('TWN','Paiwan',0.3), +('TZA','Nyakusa',5.4), +('DNK','Swedish',0.3), +('THA','Kuy',1.1), +('TGO','Moba',5.4), +('TCD','Hadjarai',6.7), +('CZE','Silesiana',0.4), +('UGA','Lango',5.9), +('UKR','Belorussian',0.3), +('HUN','Slovak',0.1), +('UZB','Tatar',1.8), +('RUS','Chechen',0.6), +('VNM','Khmer',1.4), +('USA','Chinese',0.6), +('AGO','Luvale',3.6), +('AUS','Serbo-Croatian',0.6), +('BGD','Tripuri',0.1), +('BEN','Ful',5.6), +('ZAF','Southsotho',7.6), +('ETH','Walaita',2.8), +('PHL','Pampango',3.0), +('GIN','Loma',2.3), +('IDN','Bugi',2.2), +('IND','Gujarati',4.8), +('IRN','Balochi',2.3), +('ITA','Slovene',0.2), +('AUT','Czech',0.2), +('CMR','Maka',4.9), +('CAN','Spanish',0.7), +('KEN','Meru',5.5), +('CHN','Yi',0.6), +('KGZ','Tadzhik',0.8), +('COD','Rundi',3.8), +('LBR','Loma',5.8), +('MOZ','Chuabo',5.7), +('MMR','Kachin',1.4), +('NAM','San',1.9), +('NPL','Hindi',3.0), +('NGA','Edo',3.3), +('PAK','Hindko',2.4), +('SLE','Kuranko',3.4), +('SDN','Bari',2.5), +('TZA','Chaga and Pare',4.9), +('DNK','Norwegian',0.3), +('TGO','Naudemba',4.1), +('TCD','Tandjile',6.5), +('CZE','Romani',0.3), +('UGA','Lugbara',4.7), +('UKR','Polish',0.1), +('RUS','Mordva',0.5), +('VNM','Nung',1.1), +('USA','Tagalog',0.4), +('AGO','Ambo',2.4), +('AUS','German',0.6), +('ZAF','Tsonga',4.3), +('PHL','Pangasinan',1.8), +('IDN','Banja',1.8), +('IND','Kannada',3.9), +('IRN','Arabic',2.2), +('ITA','Romani',0.2), +('AUT','Romanian',0.2), +('CMR','Masana',3.9), +('CAN','Portuguese',0.7), +('KEN','Nyika',4.8), +('CHN','Tujia',0.5), +('COD','Teke',2.7), +('LBR','Malinke',5.1), +('MOZ','Ronga',3.7), +('MMR','Kayah',0.4), +('NAM','German',0.9), +('NGA','Tiv',2.3), +('PAK','Brahui',1.2), +('SLE','Yalunka',3.4), +('SDN','Fur',2.1), +('TZA','Luguru',4.9), +('TGO','Gurma',3.4), +('TCD','Gorane',6.2), +('CZE','Hungarian',0.2), +('UGA','Gisu',4.5), +('RUS','Kazakh',0.4), +('VNM','Miao',0.9), +('USA','Polish',0.3), +('AGO','Luchazi',2.4), +('ZAF','Swazi',2.5), +('PHL','Maguindanao',1.4), +('IDN','Bali',1.7), +('IND','Malajalam',3.6), +('IRN','Bakhtyari',1.7), +('CAN','Punjabi',0.7), +('KEN','Masai',1.6), +('CHN','Mongolian',0.4), +('COD','Boa',2.3), +('MOZ','Marendje',3.5), +('NGA','Ijo',1.8), +('SDN','Chilluk',1.7), +('TZA','Shambala',4.3), +('UGA','Acholi',4.4), +('RUS','Avarian',0.4), +('VNM','Man',0.7), +('USA','Korean',0.3), +('ZAF','Venda',2.2), +('PHL','Maranao',1.3), +('IND','Orija',3.3), +('IRN','Turkmenian',1.6), +('CAN','Ukrainian',0.6), +('KEN','Turkana',1.4), +('CHN','Tibetan',0.4), +('COD','Chokwe',1.8), +('MOZ','Nyanja',3.3), +('NGA','Bura',1.6), +('SDN','Lotuko',1.5), +('TZA','Gogo',3.9), +('UGA','Rwanda',3.2), +('RUS','Mari',0.4), +('USA','Vietnamese',0.2), +('ZAF','Ndebele',1.5), +('IND','Punjabi',2.8), +('CAN','Dutch',0.5), +('CHN','Puyi',0.2), +('TZA','Ha',3.5), +('RUS','Udmur',0.3), +('USA','Japanese',0.2), +('IND','Asami',1.5), +('CAN','Eskimo Languages',0.1), +('CHN','Dong',0.2), +('RUS','Belorussian',0.3), +('USA','Portuguese',0.2); + +ANALYZE TABLE Country, City, CountryLanguage; diff --git a/mysql-test/include/world_schema.inc b/mysql-test/include/world_schema.inc new file mode 100755 index 00000000000..c683faf0114 --- /dev/null +++ b/mysql-test/include/world_schema.inc @@ -0,0 +1,25 @@ +CREATE TABLE Country ( + Code char(3) NOT NULL default '', + Name char(52) NOT NULL default '', + SurfaceArea float(10,2) NOT NULL default '0.00', + Population int(11) NOT NULL default '0', + Capital int(11) default NULL, + PRIMARY KEY (Code), + UNIQUE INDEX (Name) +); +CREATE TABLE City ( + ID int(11) NOT NULL auto_increment, + Name char(35) NOT NULL default '', + Country char(3) NOT NULL default '', + Population int(11) NOT NULL default '0', + PRIMARY KEY (ID), + INDEX (Population), + INDEX (Country) +); +CREATE TABLE CountryLanguage ( + Country char(3) NOT NULL default '', + Language char(30) NOT NULL default '', + Percentage float(3,1) NOT NULL default '0.0', + PRIMARY KEY (Country, Language), + INDEX (Percentage) +); diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result index c639b20de91..50106811169 100644 --- a/mysql-test/r/index_merge_myisam.result +++ b/mysql-test/r/index_merge_myisam.result @@ -115,11 +115,11 @@ id select_type table type possible_keys key key_len ref rows Extra explain select * from t0 where (key1 < 3 or key2 < 3) and (key3 < 100); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 range i1,i2,i3 i3 4 NULL 95 Using where +1 SIMPLE t0 index_merge i1,i2,i3 i1,i2 4,4 NULL 6 Using sort_union(i1,i2); Using where explain select * from t0 where (key1 < 3 or key2 < 3) and (key3 < 1000); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 ALL i1,i2,i3 NULL NULL NULL 1024 Using where +1 SIMPLE t0 index_merge i1,i2,i3 i1,i2 4,4 NULL 6 Using sort_union(i1,i2); Using where explain select * from t0 where ((key1 < 4 or key2 < 4) and (key2 <5 or key3 < 4)) or @@ -259,7 +259,7 @@ explain select * from t0,t1 where (t0.key1=t1.key1) and (t0.key1=3 or t0.key2=4) and t1.key1<200; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t0 ALL i1,i2 NULL NULL NULL 1024 Using where +1 SIMPLE t0 index_merge i1,i2 i1,i2 4,4 NULL 2 Using union(i1,i2); Using where 1 SIMPLE t1 ref i1 i1 4 test.t0.key1 1 explain select * from t0,t1 where (t0.key1=t1.key1) and diff --git a/mysql-test/r/range_vs_index_merge.result b/mysql-test/r/range_vs_index_merge.result new file mode 100755 index 00000000000..06c5bd4f09e --- /dev/null +++ b/mysql-test/r/range_vs_index_merge.result @@ -0,0 +1,1328 @@ +DROP TABLE IF EXISTS t1,t2,t3,t4; +DROP DATABASE IF EXISTS world; +set names utf8; +CREATE DATABASE world; +use world; +CREATE TABLE Country ( +Code char(3) NOT NULL default '', +Name char(52) NOT NULL default '', +SurfaceArea float(10,2) NOT NULL default '0.00', +Population int(11) NOT NULL default '0', +Capital int(11) default NULL, +PRIMARY KEY (Code), +UNIQUE INDEX (Name) +); +CREATE TABLE City ( +ID int(11) NOT NULL auto_increment, +Name char(35) NOT NULL default '', +Country char(3) NOT NULL default '', +Population int(11) NOT NULL default '0', +PRIMARY KEY (ID), +INDEX (Population), +INDEX (Country) +); +CREATE TABLE CountryLanguage ( +Country char(3) NOT NULL default '', +Language char(30) NOT NULL default '', +Percentage float(3,1) NOT NULL default '0.0', +PRIMARY KEY (Country, Language), +INDEX (Percentage) +); +SELECT COUNT(*) FROM Country; +COUNT(*) +239 +SELECT COUNT(*) FROM City; +COUNT(*) +4079 +SELECT COUNT(*) FROM CountryLanguage; +COUNT(*) +984 +CREATE INDEX Name ON City(Name); +EXPLAIN +SELECT * FROM City +WHERE (Population >= 100000 OR Name LIKE 'P%' OR Population < 100000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ALL Population,Name NULL NULL NULL 4079 Using where +EXPLAIN +SELECT * FROM City +WHERE (Population >= 100000 OR Name LIKE 'P%') AND Country='CAN' OR +(Population < 100000 OR Name Like 'T%') AND Country='ARG'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Country,Name Country 3 NULL 104 Using where +EXPLAIN +SELECT * FROM City +WHERE Population < 200000 AND Name LIKE 'P%' AND +(Population > 300000 OR Name LIKE 'T%') AND +(Population < 100000 OR Name LIKE 'Pa%'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Name Name 35 NULL 135 Using where +EXPLAIN +SELECT * FROM City +WHERE Population > 100000 AND Name LIKE 'Aba%' OR +Country IN ('CAN', 'ARG') AND ID < 3800 OR +Country < 'U' AND Name LIKE 'Zhu%' OR +ID BETWEEN 3800 AND 3810; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,PRIMARY 35,3,4 NULL 132 Using sort_union(Name,Country,PRIMARY); Using where +EXPLAIN +SELECT * FROM City +WHERE (Population > 101000 AND Population < 115000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population Population 4 NULL 459 Using where +EXPLAIN +SELECT * FROM City +WHERE (Population > 101000 AND Population < 103000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population Population 4 NULL 81 Using where +EXPLAIN +SELECT * FROM City +WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge Country,Name Name,Country 35,3 NULL 172 Using sort_union(Name,Country); Using where +EXPLAIN +SELECT * FROM City +WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) +AND (Population > 101000 AND Population < 115000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge Population,Country,Name Name,Country 35,3 NULL 172 Using sort_union(Name,Country); Using where +EXPLAIN +SELECT * FROM City +WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) +AND (Population > 101000 AND Population < 103000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Country,Name Population 4 NULL 81 Using where +SELECT * FROM City USE INDEX () +WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) +AND (Population > 101000 AND Population < 115000); +ID Name Country Population +403 Catanduva BRA 107761 +412 Cachoeirinha BRA 103240 +636 Bilbays EGY 113608 +637 Mit Ghamr EGY 101801 +701 Tarragona ESP 113016 +702 Lleida (Lérida) ESP 112207 +703 Jaén ESP 109247 +704 Ourense (Orense) ESP 109120 +705 Mataró ESP 104095 +706 Algeciras ESP 103106 +707 Marbella ESP 101144 +759 Gonder ETH 112249 +869 Cabuyao PHL 106630 +870 Calapan PHL 105910 +873 Cauayan PHL 103952 +1844 Cape Breton CAN 114733 +1847 Cambridge CAN 109186 +2908 Cajamarca PER 108009 +3003 Caen FRA 113987 +3411 Ceyhan TUR 102412 +3571 Calabozo VEN 107146 +3786 Cam Ranh VNM 114041 +3792 Tartu EST 101246 +4002 Carrollton USA 109576 +4027 Cape Coral USA 102286 +4032 Cambridge USA 101355 +SELECT * FROM City +WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) +AND (Population > 101000 AND Population < 115000); +ID Name Country Population +403 Catanduva BRA 107761 +412 Cachoeirinha BRA 103240 +636 Bilbays EGY 113608 +637 Mit Ghamr EGY 101801 +701 Tarragona ESP 113016 +702 Lleida (Lérida) ESP 112207 +703 Jaén ESP 109247 +704 Ourense (Orense) ESP 109120 +705 Mataró ESP 104095 +706 Algeciras ESP 103106 +707 Marbella ESP 101144 +759 Gonder ETH 112249 +869 Cabuyao PHL 106630 +870 Calapan PHL 105910 +873 Cauayan PHL 103952 +1844 Cape Breton CAN 114733 +1847 Cambridge CAN 109186 +2908 Cajamarca PER 108009 +3003 Caen FRA 113987 +3411 Ceyhan TUR 102412 +3571 Calabozo VEN 107146 +3786 Cam Ranh VNM 114041 +3792 Tartu EST 101246 +4002 Carrollton USA 109576 +4027 Cape Coral USA 102286 +4032 Cambridge USA 101355 +SELECT * FROM City USE INDEX () +WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) +AND (Population > 101000 AND Population < 103000); +ID Name Country Population +637 Mit Ghamr EGY 101801 +707 Marbella ESP 101144 +3411 Ceyhan TUR 102412 +3792 Tartu EST 101246 +4027 Cape Coral USA 102286 +4032 Cambridge USA 101355 +SELECT * FROM City +WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) +AND (Population > 101000 AND Population < 103000); +ID Name Country Population +707 Marbella ESP 101144 +3792 Tartu EST 101246 +4032 Cambridge USA 101355 +637 Mit Ghamr EGY 101801 +4027 Cape Coral USA 102286 +3411 Ceyhan TUR 102412 +EXPLAIN +SELECT * FROM City WHERE (Name < 'Ac'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 13 Using where +EXPLAIN +SELECT * FROM City WHERE (Name < 'C'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 325 Using where +EXPLAIN +SELECT * FROM City WHERE (Country > 'A' AND Country < 'B'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Country Country 3 NULL 104 Using where +EXPLAIN +SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'Pb'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 39 Using where +EXPLAIN +SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'T'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 468 Using where +EXPLAIN +SELECT * FROM City WHERE (Population > 101000 AND Population < 110000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population Population 4 NULL 328 Using where +EXPLAIN +SELECT * FROM City WHERE (Population > 103000 AND Population < 104000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population Population 4 NULL 37 Using where +EXPLAIN +SELECT * FROM City +WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Country,Name Name 35 NULL 52 Using where +EXPLAIN +SELECT * FROM City +WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge Population,Country,Name Name,Population 35,4 NULL 50 Using sort_union(Name,Population); Using where +EXPLAIN +SELECT * FROM City +WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge Population,Country,Name Country,Name 3,35 NULL 143 Using sort_union(Country,Name); Using where +EXPLAIN +SELECT * FROM City +WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge Population,Country,Name Country,Population 3,4 NULL 141 Using sort_union(Country,Population); Using where +SELECT * FROM City USE INDEX () +WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); +ID Name Country Population +65 Abu Dhabi ARE 398695 +168 Pabna BGD 103277 +189 Parakou BEN 103577 +750 Paarl ZAF 105768 +2865 Pak Pattan PAK 107800 +SELECT * FROM City +WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); +ID Name Country Population +65 Abu Dhabi ARE 398695 +750 Paarl ZAF 105768 +168 Pabna BGD 103277 +2865 Pak Pattan PAK 107800 +189 Parakou BEN 103577 +SELECT * FROM City USE INDEX () +WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +ID Name Country Population +65 Abu Dhabi ARE 398695 +168 Pabna BGD 103277 +189 Parakou BEN 103577 +914 Sekondi-Takoradi GHA 103653 +1003 Pemalang IDN 103500 +2663 Río Bravo MEX 103901 +SELECT * FROM City +WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +ID Name Country Population +65 Abu Dhabi ARE 398695 +168 Pabna BGD 103277 +189 Parakou BEN 103577 +914 Sekondi-Takoradi GHA 103653 +1003 Pemalang IDN 103500 +2663 Río Bravo MEX 103901 +SELECT * FROM City USE INDEX () +WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); +ID Name Country Population +55 Andorra la Vella AND 21189 +59 Benguela AGO 128300 +65 Abu Dhabi ARE 398695 +67 al-Ayn ARE 225970 +68 Ajman ARE 114395 +69 Buenos Aires ARG 2982146 +75 Almirante Brown ARG 538918 +85 Avellaneda ARG 353046 +93 Berazategui ARG 276916 +96 Bahía Blanca ARG 239810 +132 Brisbane AUS 1291117 +134 Adelaide AUS 978100 +144 Baku AZE 1787800 +168 Pabna BGD 103277 +189 Parakou BEN 103577 +750 Paarl ZAF 105768 +2865 Pak Pattan PAK 107800 +SELECT * FROM City +WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); +ID Name Country Population +55 Andorra la Vella AND 21189 +59 Benguela AGO 128300 +65 Abu Dhabi ARE 398695 +67 al-Ayn ARE 225970 +68 Ajman ARE 114395 +69 Buenos Aires ARG 2982146 +75 Almirante Brown ARG 538918 +85 Avellaneda ARG 353046 +93 Berazategui ARG 276916 +96 Bahía Blanca ARG 239810 +132 Brisbane AUS 1291117 +134 Adelaide AUS 978100 +144 Baku AZE 1787800 +168 Pabna BGD 103277 +189 Parakou BEN 103577 +750 Paarl ZAF 105768 +2865 Pak Pattan PAK 107800 +SELECT * FROM City USE INDEX () +WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +ID Name Country Population +55 Andorra la Vella AND 21189 +59 Benguela AGO 128300 +65 Abu Dhabi ARE 398695 +67 al-Ayn ARE 225970 +68 Ajman ARE 114395 +69 Buenos Aires ARG 2982146 +75 Almirante Brown ARG 538918 +85 Avellaneda ARG 353046 +93 Berazategui ARG 276916 +96 Bahía Blanca ARG 239810 +132 Brisbane AUS 1291117 +134 Adelaide AUS 978100 +144 Baku AZE 1787800 +168 Pabna BGD 103277 +189 Parakou BEN 103577 +914 Sekondi-Takoradi GHA 103653 +1003 Pemalang IDN 103500 +2663 Río Bravo MEX 103901 +SELECT * FROM City +WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +ID Name Country Population +55 Andorra la Vella AND 21189 +59 Benguela AGO 128300 +65 Abu Dhabi ARE 398695 +67 al-Ayn ARE 225970 +68 Ajman ARE 114395 +69 Buenos Aires ARG 2982146 +75 Almirante Brown ARG 538918 +85 Avellaneda ARG 353046 +93 Berazategui ARG 276916 +96 Bahía Blanca ARG 239810 +132 Brisbane AUS 1291117 +134 Adelaide AUS 978100 +144 Baku AZE 1787800 +168 Pabna BGD 103277 +189 Parakou BEN 103577 +914 Sekondi-Takoradi GHA 103653 +1003 Pemalang IDN 103500 +2663 Río Bravo MEX 103901 +EXPLAIN +SELECT * FROM City WHERE (ID < 50) OR (ID BETWEEN 100 AND 110); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 61 Using where +EXPLAIN +SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 300 AND 600); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 501 Using where +EXPLAIN +SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1800); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ALL PRIMARY NULL NULL NULL 4079 Using where +EXPLAIN +SELECT * FROM City WHERE Country > 'A' AND Country < 'ARG'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Country Country 3 NULL 19 Using where +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'H%' OR Name LIKE 'P%' ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 222 Using where +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'Ha%' OR Name LIKE 'Pa%' ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 72 Using where +EXPLAIN +SELECT * FROM City +WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 100 AND 110) AND +(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 61 Using where +EXPLAIN +SELECT * FROM City +WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 900 AND 1800) AND +(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,Population 35,3,4 NULL 128 Using sort_union(Name,Country,Population); Using where +EXPLAIN +SELECT * FROM City +WHERE ((ID < 600) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 300 AND 600) AND +(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,Population 35,3,4 NULL 128 Using sort_union(Name,Country,Population); Using where +SELECT * FROM City USE INDEX () +WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 100 AND 110) AND +(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); +ID Name Country Population +1 Kabul AFG 1780000 +2 Qandahar AFG 237500 +3 Herat AFG 186800 +4 Mazar-e-Sharif AFG 127800 +7 Haag NLD 440900 +16 Haarlem NLD 148772 +25 Haarlemmermeer NLD 110722 +31 Heerlen NLD 95052 +33 Willemstad ANT 2345 +34 Tirana ALB 270000 +100 Paraná ARG 207041 +102 Posadas ARG 201273 +SELECT * FROM City +WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 100 AND 110) AND +(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); +ID Name Country Population +1 Kabul AFG 1780000 +2 Qandahar AFG 237500 +3 Herat AFG 186800 +4 Mazar-e-Sharif AFG 127800 +7 Haag NLD 440900 +16 Haarlem NLD 148772 +25 Haarlemmermeer NLD 110722 +31 Heerlen NLD 95052 +33 Willemstad ANT 2345 +34 Tirana ALB 270000 +100 Paraná ARG 207041 +102 Posadas ARG 201273 +SELECT * FROM City USE INDEX() +WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 900 AND 1800) AND +(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); +ID Name Country Population +1 Kabul AFG 1780000 +2 Qandahar AFG 237500 +3 Herat AFG 186800 +4 Mazar-e-Sharif AFG 127800 +7 Haag NLD 440900 +16 Haarlem NLD 148772 +25 Haarlemmermeer NLD 110722 +33 Willemstad ANT 2345 +34 Tirana ALB 270000 +55 Andorra la Vella AND 21189 +56 Luanda AGO 2022000 +57 Huambo AGO 163100 +58 Lobito AGO 130000 +59 Benguela AGO 128300 +60 Namibe AGO 118200 +61 South Hill AIA 961 +62 The Valley AIA 595 +64 Dubai ARE 669181 +65 Abu Dhabi ARE 398695 +66 Sharja ARE 320095 +67 al-Ayn ARE 225970 +68 Ajman ARE 114395 +129 Oranjestad ABW 29034 +191 Hamilton BMU 1200 +528 Hartlepool GBR 92000 +529 Halifax GBR 91069 +914 Sekondi-Takoradi GHA 103653 +943 Palembang IDN 1222764 +950 Padang IDN 534474 +983 Palu IDN 142800 +984 Pasuruan IDN 134019 +991 Pangkal Pinang IDN 124000 +1003 Pemalang IDN 103500 +1004 Klaten IDN 103300 +1007 Palangka Raya IDN 99693 +1020 Padang Sidempuan IDN 91200 +1045 Patna IND 917243 +1114 Panihati IND 275990 +1129 Patiala IND 238368 +1142 Panipat IND 215218 +1159 Parbhani IND 190255 +1231 Pali IND 136842 +1263 Pathankot IND 123930 +1265 Palghat (Palakkad) IND 123289 +1293 Pallavaram IND 111866 +1319 Tellicherry (Thalassery) IND 103579 +1339 Palayankottai IND 97662 +1345 Patan IND 96109 +1436 Marv Dasht IRN 103579 +1468 Palermo ITA 683794 +1478 Padova ITA 211391 +1484 Parma ITA 168717 +1530 Kingston JAM 103962 +1747 Toda JPN 103969 +1748 Tajimi JPN 103171 +1785 Ibb YEM 103300 +SELECT * FROM City +WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 900 AND 1800) AND +(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); +ID Name Country Population +1 Kabul AFG 1780000 +2 Qandahar AFG 237500 +3 Herat AFG 186800 +4 Mazar-e-Sharif AFG 127800 +7 Haag NLD 440900 +16 Haarlem NLD 148772 +25 Haarlemmermeer NLD 110722 +33 Willemstad ANT 2345 +34 Tirana ALB 270000 +55 Andorra la Vella AND 21189 +56 Luanda AGO 2022000 +57 Huambo AGO 163100 +58 Lobito AGO 130000 +59 Benguela AGO 128300 +60 Namibe AGO 118200 +61 South Hill AIA 961 +62 The Valley AIA 595 +64 Dubai ARE 669181 +65 Abu Dhabi ARE 398695 +66 Sharja ARE 320095 +67 al-Ayn ARE 225970 +68 Ajman ARE 114395 +129 Oranjestad ABW 29034 +191 Hamilton BMU 1200 +528 Hartlepool GBR 92000 +529 Halifax GBR 91069 +914 Sekondi-Takoradi GHA 103653 +943 Palembang IDN 1222764 +950 Padang IDN 534474 +983 Palu IDN 142800 +984 Pasuruan IDN 134019 +991 Pangkal Pinang IDN 124000 +1003 Pemalang IDN 103500 +1004 Klaten IDN 103300 +1007 Palangka Raya IDN 99693 +1020 Padang Sidempuan IDN 91200 +1045 Patna IND 917243 +1114 Panihati IND 275990 +1129 Patiala IND 238368 +1142 Panipat IND 215218 +1159 Parbhani IND 190255 +1231 Pali IND 136842 +1263 Pathankot IND 123930 +1265 Palghat (Palakkad) IND 123289 +1293 Pallavaram IND 111866 +1319 Tellicherry (Thalassery) IND 103579 +1339 Palayankottai IND 97662 +1345 Patan IND 96109 +1436 Marv Dasht IRN 103579 +1468 Palermo ITA 683794 +1478 Padova ITA 211391 +1484 Parma ITA 168717 +1530 Kingston JAM 103962 +1747 Toda JPN 103969 +1748 Tajimi JPN 103171 +1785 Ibb YEM 103300 +SELECT * FROM City USE INDEX () +WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 300 AND 600) AND +(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); +ID Name Country Population +1 Kabul AFG 1780000 +2 Qandahar AFG 237500 +3 Herat AFG 186800 +4 Mazar-e-Sharif AFG 127800 +7 Haag NLD 440900 +16 Haarlem NLD 148772 +25 Haarlemmermeer NLD 110722 +33 Willemstad ANT 2345 +34 Tirana ALB 270000 +55 Andorra la Vella AND 21189 +56 Luanda AGO 2022000 +57 Huambo AGO 163100 +58 Lobito AGO 130000 +59 Benguela AGO 128300 +60 Namibe AGO 118200 +61 South Hill AIA 961 +62 The Valley AIA 595 +64 Dubai ARE 669181 +65 Abu Dhabi ARE 398695 +66 Sharja ARE 320095 +67 al-Ayn ARE 225970 +68 Ajman ARE 114395 +129 Oranjestad ABW 29034 +191 Hamilton BMU 1200 +339 Passo Fundo BRA 166343 +364 Parnaíba BRA 129756 +372 Paranaguá BRA 126076 +379 Palmas BRA 121919 +386 Patos de Minas BRA 119262 +411 Guaratinguetá BRA 103433 +412 Cachoeirinha BRA 103240 +413 Codó BRA 103153 +424 Passos BRA 98570 +430 Paulo Afonso BRA 97291 +435 Parnamirim BRA 96210 +448 Patos BRA 90519 +451 Palhoça BRA 89465 +517 Oldham GBR 103931 +SELECT * FROM City +WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 300 AND 600) AND +(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); +ID Name Country Population +1 Kabul AFG 1780000 +2 Qandahar AFG 237500 +3 Herat AFG 186800 +4 Mazar-e-Sharif AFG 127800 +7 Haag NLD 440900 +16 Haarlem NLD 148772 +25 Haarlemmermeer NLD 110722 +33 Willemstad ANT 2345 +34 Tirana ALB 270000 +55 Andorra la Vella AND 21189 +56 Luanda AGO 2022000 +57 Huambo AGO 163100 +58 Lobito AGO 130000 +59 Benguela AGO 128300 +60 Namibe AGO 118200 +61 South Hill AIA 961 +62 The Valley AIA 595 +64 Dubai ARE 669181 +65 Abu Dhabi ARE 398695 +66 Sharja ARE 320095 +67 al-Ayn ARE 225970 +68 Ajman ARE 114395 +129 Oranjestad ABW 29034 +191 Hamilton BMU 1200 +339 Passo Fundo BRA 166343 +364 Parnaíba BRA 129756 +372 Paranaguá BRA 126076 +379 Palmas BRA 121919 +386 Patos de Minas BRA 119262 +411 Guaratinguetá BRA 103433 +412 Cachoeirinha BRA 103240 +413 Codó BRA 103153 +424 Passos BRA 98570 +430 Paulo Afonso BRA 97291 +435 Parnamirim BRA 96210 +448 Patos BRA 90519 +451 Palhoça BRA 89465 +517 Oldham GBR 103931 +EXPLAIN +SELECT * FROM City WHERE Population > 101000 AND Population < 102000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population Population 4 NULL 39 Using where +EXPLAIN +SELECT * FROM City WHERE Population > 101000 AND Population < 110000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population Population 4 NULL 328 Using where +EXPLAIN +SELECT * FROM City WHERE Country < 'C'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Country Country 3 NULL 436 Using where +EXPLAIN +SELECT * FROM City WHERE Country < 'AGO'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Country Country 3 NULL 6 Using where +EXPLAIN +SELECT * FROM City WHERE Name BETWEEN 'P' AND 'T'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 468 Using where +EXPLAIN +SELECT * FROM City WHERE Name BETWEEN 'P' AND 'Pb'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 39 Using where +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 3400 AND 3800; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 401 Using where +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'P%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 135 Using where +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 102000) AND +(Country < 'C' OR Name BETWEEN 'P' AND 'T')) OR +((ID BETWEEN 3400 AND 3800) AND +(Country < 'AGO' OR Name LIKE 'Pa%')); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge PRIMARY,Population,Country,Name Country,Name,Population 3,35,4 NULL 84 Using sort_union(Country,Name,Population); Using where +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 110000) AND +(Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR +((ID BETWEEN 3790 AND 3800) AND +(Country < 'C' OR Name LIKE 'P%')); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge PRIMARY,Population,Country,Name Country,Name,PRIMARY 3,35,4 NULL 56 Using sort_union(Country,Name,PRIMARY); Using where +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 AND Population < 102000) AND +(Country < 'C' OR Name BETWEEN 'P' AND 'T')) OR +((ID BETWEEN 3400 AND 3800) AND +(Country < 'AGO' OR Name LIKE 'Pa%')); +ID Name Country Population +169 Naogaon BGD 101266 +205 Francistown BWA 101805 +417 Itaituba BRA 101320 +418 Araras BRA 101046 +751 Potchefstroom ZAF 101817 +1752 Sakata JPN 101651 +1851 Saint John´s CAN 101936 +1853 Saanich CAN 101388 +2909 Puno PER 101578 +3463 Pavlograd UKR 127000 +4030 Sandy USA 101853 +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 102000) AND +(Country < 'C' OR Name BETWEEN 'P' AND 'T')) OR +((ID BETWEEN 3400 AND 3800) AND +(Country < 'AGO' OR Name LIKE 'Pa%')); +ID Name Country Population +169 Naogaon BGD 101266 +205 Francistown BWA 101805 +417 Itaituba BRA 101320 +418 Araras BRA 101046 +751 Potchefstroom ZAF 101817 +1752 Sakata JPN 101651 +1851 Saint John´s CAN 101936 +1853 Saanich CAN 101388 +2909 Puno PER 101578 +3463 Pavlograd UKR 127000 +4030 Sandy USA 101853 +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 AND Population < 110000) AND +(Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR +((ID BETWEEN 3790 AND 3800) AND +(Country < 'C' OR Name LIKE 'P%')); +ID Name Country Population +168 Pabna BGD 103277 +189 Parakou BEN 103577 +750 Paarl ZAF 105768 +2865 Pak Pattan PAK 107800 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 110000) AND +(Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR +((ID BETWEEN 3790 AND 3800) AND +(Country < 'C' OR Name LIKE 'P%')); +ID Name Country Population +168 Pabna BGD 103277 +189 Parakou BEN 103577 +750 Paarl ZAF 105768 +2865 Pak Pattan PAK 107800 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +CREATE INDEX CountryPopulation ON City(Country,Population); +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'Pas%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 5 Using where +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'P%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 135 Using where +EXPLAIN +SELECT * FROM City WHERE (Population > 101000 AND Population < 103000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population Population 4 NULL 81 Using where +EXPLAIN +SELECT * FROM City WHERE Country='USA'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ref Country,CountryPopulation Country 3 const 267 Using where +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') +AND Country='USA'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge Population,Country,Name,CountryPopulation CountryPopulation,Name 7,35 NULL 15 Using sort_union(CountryPopulation,Name); Using where +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') +AND Country='USA'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ref Population,Country,Name,CountryPopulation Country 3 const 267 Using where +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') +AND Country='USA'; +ID Name Country Population +3943 Pasadena USA 141674 +3953 Pasadena USA 133936 +4023 Gary USA 102746 +4024 Berkeley USA 102743 +4025 Santa Clara USA 102361 +4026 Green Bay USA 102313 +4027 Cape Coral USA 102286 +4028 Arvada USA 102153 +4029 Pueblo USA 102121 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') +AND Country='USA'; +ID Name Country Population +3943 Pasadena USA 141674 +3953 Pasadena USA 133936 +4023 Gary USA 102746 +4024 Berkeley USA 102743 +4025 Santa Clara USA 102361 +4026 Green Bay USA 102313 +4027 Cape Coral USA 102286 +4028 Arvada USA 102153 +4029 Pueblo USA 102121 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') +AND Country='USA'; +ID Name Country Population +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3820 Portland USA 529121 +3844 Pittsburgh USA 334563 +3870 Plano USA 222030 +3912 Providence USA 173618 +3930 Pomona USA 149473 +3932 Paterson USA 149222 +3943 Pasadena USA 141674 +3951 Pembroke Pines USA 137427 +3953 Pasadena USA 133936 +3967 Paradise USA 124682 +3986 Palmdale USA 116670 +3996 Peoria USA 112936 +4007 Peoria USA 108364 +4016 Provo USA 105166 +4023 Gary USA 102746 +4024 Berkeley USA 102743 +4025 Santa Clara USA 102361 +4026 Green Bay USA 102313 +4027 Cape Coral USA 102286 +4028 Arvada USA 102153 +4029 Pueblo USA 102121 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +4035 Portsmouth USA 100565 +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') +AND Country='USA'; +ID Name Country Population +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3820 Portland USA 529121 +3844 Pittsburgh USA 334563 +3870 Plano USA 222030 +3912 Providence USA 173618 +3930 Pomona USA 149473 +3932 Paterson USA 149222 +3943 Pasadena USA 141674 +3951 Pembroke Pines USA 137427 +3953 Pasadena USA 133936 +3967 Paradise USA 124682 +3986 Palmdale USA 116670 +3996 Peoria USA 112936 +4007 Peoria USA 108364 +4016 Provo USA 105166 +4023 Gary USA 102746 +4024 Berkeley USA 102743 +4025 Santa Clara USA 102361 +4026 Green Bay USA 102313 +4027 Cape Coral USA 102286 +4028 Arvada USA 102153 +4029 Pueblo USA 102121 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +4035 Portsmouth USA 100565 +CREATE INDEX CountryName ON City(Country,Name); +EXPLAIN +SELECT * FROM City WHERE Country='USA'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 267 Using where +EXPLAIN +SELECT * FROM City WHERE Country='BRA'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ref Country,CountryPopulation,CountryName CountryName 3 const 221 Using where +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 4025 AND 4035; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 4028 AND 4032; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 5 Using where +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 3500 AND 3800; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 301 Using where +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 4000 AND 4300; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 80 Using where +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 250 and 260 ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where +EXPLAIN +SELECT * FROM City WHERE (Population > 101000 AND Population < 102000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population Population 4 NULL 39 Using where +EXPLAIN +SELECT * FROM City WHERE (Population > 101000 AND Population < 103000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population Population 4 NULL 81 Using where +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'Pa%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 41 Using where +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryPopulation,PRIMARY 7,4 NULL 14 Using sort_union(CountryPopulation,PRIMARY); Using where +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 103000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName,PRIMARY 38,4 NULL 11 Using sort_union(CountryName,PRIMARY); Using where +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 110000) OR +ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name BETWEEN 'P' AND 'T' OR ID BETWEEN 4000 AND 4300); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ref PRIMARY,Population,Country,Name,CountryPopulation,CountryName Country 3 const 267 Using where +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 AND Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); +ID Name Country Population +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); +ID Name Country Population +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 AND Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032); +ID Name Country Population +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032); +ID Name Country Population +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 AND Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); +ID Name Country Population +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); +ID Name Country Population +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 and Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryPopulation,PRIMARY,CountryName 7,4,38 NULL 35 Using sort_union(CountryPopulation,PRIMARY,CountryName); Using where +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 and Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA'; +ID Name Country Population +250 Mauá BRA 375055 +251 Carapicuíba BRA 357552 +252 Olinda BRA 354732 +253 Campina Grande BRA 352497 +254 São José do Rio Preto BRA 351944 +255 Caxias do Sul BRA 349581 +256 Moji das Cruzes BRA 339194 +257 Diadema BRA 335078 +258 Aparecida de Goiânia BRA 324662 +259 Piracicaba BRA 319104 +260 Cariacica BRA 319033 +285 Paulista BRA 248473 +339 Passo Fundo BRA 166343 +364 Parnaíba BRA 129756 +372 Paranaguá BRA 126076 +379 Palmas BRA 121919 +386 Patos de Minas BRA 119262 +424 Passos BRA 98570 +430 Paulo Afonso BRA 97291 +435 Parnamirim BRA 96210 +448 Patos BRA 90519 +451 Palhoça BRA 89465 +3793 New York USA 8008278 +3794 Los Angeles USA 3694820 +3795 Chicago USA 2896016 +3796 Houston USA 1953631 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3799 San Diego USA 1223400 +3800 Dallas USA 1188580 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City +WHERE ((Population > 101000 and Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA'; +ID Name Country Population +250 Mauá BRA 375055 +251 Carapicuíba BRA 357552 +252 Olinda BRA 354732 +253 Campina Grande BRA 352497 +254 São José do Rio Preto BRA 351944 +255 Caxias do Sul BRA 349581 +256 Moji das Cruzes BRA 339194 +257 Diadema BRA 335078 +258 Aparecida de Goiânia BRA 324662 +259 Piracicaba BRA 319104 +260 Cariacica BRA 319033 +285 Paulista BRA 248473 +339 Passo Fundo BRA 166343 +364 Parnaíba BRA 129756 +372 Paranaguá BRA 126076 +379 Palmas BRA 121919 +386 Patos de Minas BRA 119262 +424 Passos BRA 98570 +430 Paulo Afonso BRA 97291 +435 Parnamirim BRA 96210 +448 Patos BRA 90519 +451 Palhoça BRA 89465 +3793 New York USA 8008278 +3794 Los Angeles USA 3694820 +3795 Chicago USA 2896016 +3796 Houston USA 1953631 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3799 San Diego USA 1223400 +3800 Dallas USA 1188580 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 11000) OR +ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName 38 NULL 23 Using where +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 11000) OR +ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country,Name,CountryPopulation,CountryName Name 35 NULL 1 Using where +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 AND Population < 11000) OR +ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300); +ID Name Country Population +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 11000) OR +ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300); +ID Name Country Population +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 AND Population < 11000) OR +ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300); +ID Name Country Population +3798 Phoenix USA 1321045 +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 11000) OR +ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300); +ID Name Country Population +3798 Phoenix USA 1321045 +DROP DATABASE world; +use test; +CREATE TABLE t1 ( +id int(10) unsigned NOT NULL auto_increment, +account_id int(10) unsigned NOT NULL, +first_name varchar(50) default NULL, +middle_name varchar(50) default NULL, +last_name varchar(100) default NULL, +home_address_1 varchar(150) default NULL, +home_city varchar(75) default NULL, +home_state char(2) default NULL, +home_postal_code varchar(50) default NULL, +home_county varchar(75) default NULL, +home_country char(3) default NULL, +work_address_1 varchar(150) default NULL, +work_city varchar(75) default NULL, +work_state char(2) default NULL, +work_postal_code varchar(50) default NULL, +work_county varchar(75) default NULL, +work_country char(3) default NULL, +login varchar(50) NOT NULL, +PRIMARY KEY (id), +KEY login (login,account_id), +KEY account_id (account_id), +KEY user_home_country_indx (home_country), +KEY user_work_country_indx (work_country), +KEY user_home_state_indx (home_state), +KEY user_work_state_indx (work_state), +KEY user_home_city_indx (home_city), +KEY user_work_city_indx (work_city), +KEY user_first_name_indx (first_name), +KEY user_last_name_indx (last_name) +); +insert into t1(account_id, login, home_state, work_state) values +(1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'), +(1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'); +insert into t1(account_id, login, home_state, work_state) +select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) +select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) +select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) +select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) +select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) +select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) +select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) +select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) +select 1, 'pw', 'ak', 'ak' from t1; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +select count(*) from t1 where account_id = 1; +count(*) +3072 +select * from t1 +where (home_state = 'ia' or work_state='ia') and account_id = 1; +id account_id first_name middle_name last_name home_address_1 home_city home_state home_postal_code home_county home_country work_address_1 work_city work_state work_postal_code work_county work_country login +1 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw +2 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw +3 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw +4 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw +5 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw +6 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw +explain +select * from t1 +where (home_state = 'ia' or work_state='ia') and account_id = 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge account_id,user_home_state_indx,user_work_state_indx user_home_state_indx,user_work_state_indx 3,3 NULL 6 Using union(user_home_state_indx,user_work_state_indx); Using where +drop table t1; +CREATE TABLE t1 ( +c1 int(11) NOT NULL auto_increment, +c2 decimal(10,0) default NULL, +c3 decimal(10,0) default NULL, +c4 decimal(10,0) default NULL, +c5 decimal(10,0) default NULL, +cp decimal(1,0) default NULL, +ce decimal(10,0) default NULL, +cdata char(20), +PRIMARY KEY (c1), +KEY k1 (c2,c3,cp,ce), +KEY k2 (c4,c5,cp,ce) +); +insert into t1 (c2, c3, c4, c5, cp) values(1,1,1,1,1); +insert into t1 (c2, c3, c4, c5, cp) values(2,1,1,1,4); +insert into t1 (c2, c3, c4, c5, cp) values(2,1,2,1,1); +insert into t1 (c2, c3, c4, c5, cp) values(2,1,3,1,4); +insert into t1 (c2, c3, c4, c5, cp) values(3,1,4,1,4); +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +explain +select * from t1 where (c2=1 and c3=1) or (c4=2 and c5=1); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge k1,k2 k1,k2 12,12 NULL 2 Using sort_union(k1,k2); Using where +explain +select * from t1 +where (c2=1 and c3=1 and cp=1) or (c4=2 and c5=1 and cp=1); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge k1,k2 k1,k2 14,14 NULL 2 Using sort_union(k1,k2); Using where +explain +select * from t1 +where ((c2=1 and c3=1) or (c4=2 and c5=1)) and cp=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge k1,k2 k1,k2 14,14 NULL 2 Using sort_union(k1,k2); Using where +select * from t1 +where (c2=1 and c3=1 and cp=1) or (c4=2 and c5=1 and cp=1); +c1 c2 c3 c4 c5 cp ce cdata +1 1 1 1 1 1 NULL NULL +3 2 1 2 1 1 NULL NULL +select * from t1 +where ((c2=1 and c3=1) or (c4=2 and c5=1)) and cp=1; +c1 c2 c3 c4 c5 cp ce cdata +1 1 1 1 1 1 NULL NULL +3 2 1 2 1 1 NULL NULL +drop table t1; +create table t1 ( +c1 int auto_increment primary key, +c2 char(20), +c3 char (20), +c4 int +); +alter table t1 add key k1 (c2); +alter table t1 add key k2 (c3); +alter table t1 add key k3 (c4); +insert into t1 values(null, 'a', 'b', 0); +insert into t1 values(null, 'c', 'b', 0); +insert into t1 values(null, 'a', 'd', 0); +insert into t1 values(null, 'ccc', 'qqq', 0); +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3,c4) select c2,c3,1 from t1 where c2 != 'a'; +insert into t1 (c2,c3,c4) select c2,c3,2 from t1 where c2 != 'a'; +insert into t1 (c2,c3,c4) select c2,c3,3 from t1 where c2 != 'a'; +insert into t1 (c2,c3,c4) select c2,c3,4 from t1 where c2 != 'a'; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +select count(*) from t1 where (c2='e' OR c3='q'); +count(*) +0 +select count(*) from t1 where c4 != 0; +count(*) +3840 +explain +select distinct c1 from t1 where (c2='e' OR c3='q'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge k1,k2 k1,k2 21,21 NULL 2 Using union(k1,k2); Using where +explain +select distinct c1 from t1 where (c4!= 0) AND (c2='e' OR c3='q'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge k1,k2,k3 k1,k2 21,21 NULL 2 Using union(k1,k2); Using where +drop table t1; +create table t1 ( +id int unsigned auto_increment primary key, +c1 char(12), +c2 char(15), +c3 char(1) +); +insert into t1 (c3) values ('1'), ('2'); +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +update t1 set c1=lpad(id+1000, 12, ' '), c2=lpad(id+10000, 15, ' '); +alter table t1 add unique index (c1), add unique index (c2), add index (c3); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +explain +select * from t1 where (c1=' 100000' or c2=' 2000000'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge c1,c2 c1,c2 13,16 NULL 2 Using union(c1,c2); Using where +explain +select * from t1 where (c1=' 100000' or c2=' 2000000') and c3='2'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge c1,c2,c3 c1,c2 13,16 NULL 2 Using union(c1,c2); Using where +select * from t1 where (c1=' 100000' or c2=' 2000000'); +id c1 c2 c3 +select * from t1 where (c1=' 100000' or c2=' 2000000') and c3='2'; +id c1 c2 c3 +drop table t1; diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result new file mode 100755 index 00000000000..2e949bd47ce --- /dev/null +++ b/mysql-test/r/range_vs_index_merge_innodb.result @@ -0,0 +1,1330 @@ +SET SESSION STORAGE_ENGINE='InnoDB'; +DROP TABLE IF EXISTS t1,t2,t3,t4; +DROP DATABASE IF EXISTS world; +set names utf8; +CREATE DATABASE world; +use world; +CREATE TABLE Country ( +Code char(3) NOT NULL default '', +Name char(52) NOT NULL default '', +SurfaceArea float(10,2) NOT NULL default '0.00', +Population int(11) NOT NULL default '0', +Capital int(11) default NULL, +PRIMARY KEY (Code), +UNIQUE INDEX (Name) +); +CREATE TABLE City ( +ID int(11) NOT NULL auto_increment, +Name char(35) NOT NULL default '', +Country char(3) NOT NULL default '', +Population int(11) NOT NULL default '0', +PRIMARY KEY (ID), +INDEX (Population), +INDEX (Country) +); +CREATE TABLE CountryLanguage ( +Country char(3) NOT NULL default '', +Language char(30) NOT NULL default '', +Percentage float(3,1) NOT NULL default '0.0', +PRIMARY KEY (Country, Language), +INDEX (Percentage) +); +SELECT COUNT(*) FROM Country; +COUNT(*) +239 +SELECT COUNT(*) FROM City; +COUNT(*) +4079 +SELECT COUNT(*) FROM CountryLanguage; +COUNT(*) +984 +CREATE INDEX Name ON City(Name); +EXPLAIN +SELECT * FROM City +WHERE (Population >= 100000 OR Name LIKE 'P%' OR Population < 100000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ALL Population,Name NULL NULL NULL 4249 Using where +EXPLAIN +SELECT * FROM City +WHERE (Population >= 100000 OR Name LIKE 'P%') AND Country='CAN' OR +(Population < 100000 OR Name Like 'T%') AND Country='ARG'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Country,Name Country 3 NULL 106 Using where +EXPLAIN +SELECT * FROM City +WHERE Population < 200000 AND Name LIKE 'P%' AND +(Population > 300000 OR Name LIKE 'T%') AND +(Population < 100000 OR Name LIKE 'Pa%'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Name Name 35 NULL 235 Using where +EXPLAIN +SELECT * FROM City +WHERE Population > 100000 AND Name LIKE 'Aba%' OR +Country IN ('CAN', 'ARG') AND ID < 3800 OR +Country < 'U' AND Name LIKE 'Zhu%' OR +ID BETWEEN 3800 AND 3810; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,PRIMARY 35,3,4 NULL 125 Using sort_union(Name,Country,PRIMARY); Using where +EXPLAIN +SELECT * FROM City +WHERE (Population > 101000 AND Population < 115000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population Population 4 NULL 458 Using where +EXPLAIN +SELECT * FROM City +WHERE (Population > 101000 AND Population < 103000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population Population 4 NULL 80 Using where +EXPLAIN +SELECT * FROM City +WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge Country,Name Name,Country 35,3 NULL 213 Using sort_union(Name,Country); Using where +EXPLAIN +SELECT * FROM City +WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) +AND (Population > 101000 AND Population < 115000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge Population,Country,Name Name,Country 35,3 NULL 213 Using sort_union(Name,Country); Using where +EXPLAIN +SELECT * FROM City +WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) +AND (Population > 101000 AND Population < 103000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Country,Name Population 4 NULL 80 Using where +SELECT * FROM City USE INDEX () +WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) +AND (Population > 101000 AND Population < 115000); +ID Name Country Population +403 Catanduva BRA 107761 +412 Cachoeirinha BRA 103240 +636 Bilbays EGY 113608 +637 Mit Ghamr EGY 101801 +701 Tarragona ESP 113016 +702 Lleida (Lérida) ESP 112207 +703 Jaén ESP 109247 +704 Ourense (Orense) ESP 109120 +705 Mataró ESP 104095 +706 Algeciras ESP 103106 +707 Marbella ESP 101144 +759 Gonder ETH 112249 +869 Cabuyao PHL 106630 +870 Calapan PHL 105910 +873 Cauayan PHL 103952 +1844 Cape Breton CAN 114733 +1847 Cambridge CAN 109186 +2908 Cajamarca PER 108009 +3003 Caen FRA 113987 +3411 Ceyhan TUR 102412 +3571 Calabozo VEN 107146 +3786 Cam Ranh VNM 114041 +3792 Tartu EST 101246 +4002 Carrollton USA 109576 +4027 Cape Coral USA 102286 +4032 Cambridge USA 101355 +SELECT * FROM City +WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) +AND (Population > 101000 AND Population < 115000); +ID Name Country Population +403 Catanduva BRA 107761 +412 Cachoeirinha BRA 103240 +636 Bilbays EGY 113608 +637 Mit Ghamr EGY 101801 +701 Tarragona ESP 113016 +702 Lleida (Lérida) ESP 112207 +703 Jaén ESP 109247 +704 Ourense (Orense) ESP 109120 +705 Mataró ESP 104095 +706 Algeciras ESP 103106 +707 Marbella ESP 101144 +759 Gonder ETH 112249 +869 Cabuyao PHL 106630 +870 Calapan PHL 105910 +873 Cauayan PHL 103952 +1844 Cape Breton CAN 114733 +1847 Cambridge CAN 109186 +2908 Cajamarca PER 108009 +3003 Caen FRA 113987 +3411 Ceyhan TUR 102412 +3571 Calabozo VEN 107146 +3786 Cam Ranh VNM 114041 +3792 Tartu EST 101246 +4002 Carrollton USA 109576 +4027 Cape Coral USA 102286 +4032 Cambridge USA 101355 +SELECT * FROM City USE INDEX () +WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) +AND (Population > 101000 AND Population < 103000); +ID Name Country Population +637 Mit Ghamr EGY 101801 +707 Marbella ESP 101144 +3411 Ceyhan TUR 102412 +3792 Tartu EST 101246 +4027 Cape Coral USA 102286 +4032 Cambridge USA 101355 +SELECT * FROM City +WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) +AND (Population > 101000 AND Population < 103000); +ID Name Country Population +707 Marbella ESP 101144 +3792 Tartu EST 101246 +4032 Cambridge USA 101355 +637 Mit Ghamr EGY 101801 +4027 Cape Coral USA 102286 +3411 Ceyhan TUR 102412 +EXPLAIN +SELECT * FROM City WHERE (Name < 'Ac'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 23 Using where +EXPLAIN +SELECT * FROM City WHERE (Name < 'C'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ALL Name NULL NULL NULL 4249 Using where +EXPLAIN +SELECT * FROM City WHERE (Country > 'A' AND Country < 'B'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Country Country 3 NULL 106 Using where +EXPLAIN +SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'Pb'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 71 Using where +EXPLAIN +SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'T'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ALL Name NULL NULL NULL 4249 Using where +EXPLAIN +SELECT * FROM City WHERE (Population > 101000 AND Population < 110000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population Population 4 NULL 327 Using where +EXPLAIN +SELECT * FROM City WHERE (Population > 103000 AND Population < 104000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population Population 4 NULL 36 Using where +EXPLAIN +SELECT * FROM City +WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Country,Name Name 35 NULL 94 Using where +EXPLAIN +SELECT * FROM City +WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge Population,Country,Name Name,Population 35,4 NULL 59 Using sort_union(Name,Population); Using where +EXPLAIN +SELECT * FROM City +WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge Population,Country,Name Country,Name 3,35 NULL 177 Using sort_union(Country,Name); Using where +EXPLAIN +SELECT * FROM City +WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge Population,Country,Name Country,Population 3,4 NULL 142 Using sort_union(Country,Population); Using where +SELECT * FROM City USE INDEX () +WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); +ID Name Country Population +65 Abu Dhabi ARE 398695 +168 Pabna BGD 103277 +189 Parakou BEN 103577 +750 Paarl ZAF 105768 +2865 Pak Pattan PAK 107800 +SELECT * FROM City +WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); +ID Name Country Population +65 Abu Dhabi ARE 398695 +750 Paarl ZAF 105768 +168 Pabna BGD 103277 +2865 Pak Pattan PAK 107800 +189 Parakou BEN 103577 +SELECT * FROM City USE INDEX () +WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +ID Name Country Population +65 Abu Dhabi ARE 398695 +168 Pabna BGD 103277 +189 Parakou BEN 103577 +914 Sekondi-Takoradi GHA 103653 +1003 Pemalang IDN 103500 +2663 Río Bravo MEX 103901 +SELECT * FROM City +WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +ID Name Country Population +65 Abu Dhabi ARE 398695 +168 Pabna BGD 103277 +189 Parakou BEN 103577 +914 Sekondi-Takoradi GHA 103653 +1003 Pemalang IDN 103500 +2663 Río Bravo MEX 103901 +SELECT * FROM City USE INDEX () +WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); +ID Name Country Population +55 Andorra la Vella AND 21189 +59 Benguela AGO 128300 +65 Abu Dhabi ARE 398695 +67 al-Ayn ARE 225970 +68 Ajman ARE 114395 +69 Buenos Aires ARG 2982146 +75 Almirante Brown ARG 538918 +85 Avellaneda ARG 353046 +93 Berazategui ARG 276916 +96 Bahía Blanca ARG 239810 +132 Brisbane AUS 1291117 +134 Adelaide AUS 978100 +144 Baku AZE 1787800 +168 Pabna BGD 103277 +189 Parakou BEN 103577 +750 Paarl ZAF 105768 +2865 Pak Pattan PAK 107800 +SELECT * FROM City +WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); +ID Name Country Population +55 Andorra la Vella AND 21189 +59 Benguela AGO 128300 +65 Abu Dhabi ARE 398695 +67 al-Ayn ARE 225970 +68 Ajman ARE 114395 +69 Buenos Aires ARG 2982146 +75 Almirante Brown ARG 538918 +85 Avellaneda ARG 353046 +93 Berazategui ARG 276916 +96 Bahía Blanca ARG 239810 +132 Brisbane AUS 1291117 +134 Adelaide AUS 978100 +144 Baku AZE 1787800 +168 Pabna BGD 103277 +189 Parakou BEN 103577 +750 Paarl ZAF 105768 +2865 Pak Pattan PAK 107800 +SELECT * FROM City USE INDEX () +WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +ID Name Country Population +55 Andorra la Vella AND 21189 +59 Benguela AGO 128300 +65 Abu Dhabi ARE 398695 +67 al-Ayn ARE 225970 +68 Ajman ARE 114395 +69 Buenos Aires ARG 2982146 +75 Almirante Brown ARG 538918 +85 Avellaneda ARG 353046 +93 Berazategui ARG 276916 +96 Bahía Blanca ARG 239810 +132 Brisbane AUS 1291117 +134 Adelaide AUS 978100 +144 Baku AZE 1787800 +168 Pabna BGD 103277 +189 Parakou BEN 103577 +914 Sekondi-Takoradi GHA 103653 +1003 Pemalang IDN 103500 +2663 Río Bravo MEX 103901 +SELECT * FROM City +WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +ID Name Country Population +55 Andorra la Vella AND 21189 +59 Benguela AGO 128300 +65 Abu Dhabi ARE 398695 +67 al-Ayn ARE 225970 +68 Ajman ARE 114395 +69 Buenos Aires ARG 2982146 +75 Almirante Brown ARG 538918 +85 Avellaneda ARG 353046 +93 Berazategui ARG 276916 +96 Bahía Blanca ARG 239810 +132 Brisbane AUS 1291117 +134 Adelaide AUS 978100 +144 Baku AZE 1787800 +168 Pabna BGD 103277 +189 Parakou BEN 103577 +914 Sekondi-Takoradi GHA 103653 +1003 Pemalang IDN 103500 +2663 Río Bravo MEX 103901 +EXPLAIN +SELECT * FROM City WHERE (ID < 50) OR (ID BETWEEN 100 AND 110); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 60 Using where +EXPLAIN +SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 300 AND 600); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 1142 Using where +EXPLAIN +SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1800); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 2950 Using where +EXPLAIN +SELECT * FROM City WHERE Country > 'A' AND Country < 'ARG'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Country Country 3 NULL 19 Using where +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'H%' OR Name LIKE 'P%' ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 394 Using where +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'Ha%' OR Name LIKE 'Pa%' ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 133 Using where +EXPLAIN +SELECT * FROM City +WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 100 AND 110) AND +(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 60 Using where +EXPLAIN +SELECT * FROM City +WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 900 AND 1800) AND +(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,Population 35,3,4 NULL 188 Using sort_union(Name,Country,Population); Using where +EXPLAIN +SELECT * FROM City +WHERE ((ID < 600) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 300 AND 600) AND +(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 1062 Using where +SELECT * FROM City USE INDEX () +WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 100 AND 110) AND +(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); +ID Name Country Population +1 Kabul AFG 1780000 +2 Qandahar AFG 237500 +3 Herat AFG 186800 +4 Mazar-e-Sharif AFG 127800 +7 Haag NLD 440900 +16 Haarlem NLD 148772 +25 Haarlemmermeer NLD 110722 +31 Heerlen NLD 95052 +33 Willemstad ANT 2345 +34 Tirana ALB 270000 +100 Paraná ARG 207041 +102 Posadas ARG 201273 +SELECT * FROM City +WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 100 AND 110) AND +(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); +ID Name Country Population +1 Kabul AFG 1780000 +2 Qandahar AFG 237500 +3 Herat AFG 186800 +4 Mazar-e-Sharif AFG 127800 +7 Haag NLD 440900 +16 Haarlem NLD 148772 +25 Haarlemmermeer NLD 110722 +31 Heerlen NLD 95052 +33 Willemstad ANT 2345 +34 Tirana ALB 270000 +100 Paraná ARG 207041 +102 Posadas ARG 201273 +SELECT * FROM City USE INDEX() +WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 900 AND 1800) AND +(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); +ID Name Country Population +1 Kabul AFG 1780000 +2 Qandahar AFG 237500 +3 Herat AFG 186800 +4 Mazar-e-Sharif AFG 127800 +7 Haag NLD 440900 +16 Haarlem NLD 148772 +25 Haarlemmermeer NLD 110722 +33 Willemstad ANT 2345 +34 Tirana ALB 270000 +55 Andorra la Vella AND 21189 +56 Luanda AGO 2022000 +57 Huambo AGO 163100 +58 Lobito AGO 130000 +59 Benguela AGO 128300 +60 Namibe AGO 118200 +61 South Hill AIA 961 +62 The Valley AIA 595 +64 Dubai ARE 669181 +65 Abu Dhabi ARE 398695 +66 Sharja ARE 320095 +67 al-Ayn ARE 225970 +68 Ajman ARE 114395 +129 Oranjestad ABW 29034 +191 Hamilton BMU 1200 +528 Hartlepool GBR 92000 +529 Halifax GBR 91069 +914 Sekondi-Takoradi GHA 103653 +943 Palembang IDN 1222764 +950 Padang IDN 534474 +983 Palu IDN 142800 +984 Pasuruan IDN 134019 +991 Pangkal Pinang IDN 124000 +1003 Pemalang IDN 103500 +1004 Klaten IDN 103300 +1007 Palangka Raya IDN 99693 +1020 Padang Sidempuan IDN 91200 +1045 Patna IND 917243 +1114 Panihati IND 275990 +1129 Patiala IND 238368 +1142 Panipat IND 215218 +1159 Parbhani IND 190255 +1231 Pali IND 136842 +1263 Pathankot IND 123930 +1265 Palghat (Palakkad) IND 123289 +1293 Pallavaram IND 111866 +1319 Tellicherry (Thalassery) IND 103579 +1339 Palayankottai IND 97662 +1345 Patan IND 96109 +1436 Marv Dasht IRN 103579 +1468 Palermo ITA 683794 +1478 Padova ITA 211391 +1484 Parma ITA 168717 +1530 Kingston JAM 103962 +1747 Toda JPN 103969 +1748 Tajimi JPN 103171 +1785 Ibb YEM 103300 +SELECT * FROM City +WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 900 AND 1800) AND +(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); +ID Name Country Population +1 Kabul AFG 1780000 +2 Qandahar AFG 237500 +3 Herat AFG 186800 +4 Mazar-e-Sharif AFG 127800 +7 Haag NLD 440900 +16 Haarlem NLD 148772 +25 Haarlemmermeer NLD 110722 +33 Willemstad ANT 2345 +34 Tirana ALB 270000 +55 Andorra la Vella AND 21189 +56 Luanda AGO 2022000 +57 Huambo AGO 163100 +58 Lobito AGO 130000 +59 Benguela AGO 128300 +60 Namibe AGO 118200 +61 South Hill AIA 961 +62 The Valley AIA 595 +64 Dubai ARE 669181 +65 Abu Dhabi ARE 398695 +66 Sharja ARE 320095 +67 al-Ayn ARE 225970 +68 Ajman ARE 114395 +129 Oranjestad ABW 29034 +191 Hamilton BMU 1200 +528 Hartlepool GBR 92000 +529 Halifax GBR 91069 +914 Sekondi-Takoradi GHA 103653 +943 Palembang IDN 1222764 +950 Padang IDN 534474 +983 Palu IDN 142800 +984 Pasuruan IDN 134019 +991 Pangkal Pinang IDN 124000 +1003 Pemalang IDN 103500 +1004 Klaten IDN 103300 +1007 Palangka Raya IDN 99693 +1020 Padang Sidempuan IDN 91200 +1045 Patna IND 917243 +1114 Panihati IND 275990 +1129 Patiala IND 238368 +1142 Panipat IND 215218 +1159 Parbhani IND 190255 +1231 Pali IND 136842 +1263 Pathankot IND 123930 +1265 Palghat (Palakkad) IND 123289 +1293 Pallavaram IND 111866 +1319 Tellicherry (Thalassery) IND 103579 +1339 Palayankottai IND 97662 +1345 Patan IND 96109 +1436 Marv Dasht IRN 103579 +1468 Palermo ITA 683794 +1478 Padova ITA 211391 +1484 Parma ITA 168717 +1530 Kingston JAM 103962 +1747 Toda JPN 103969 +1748 Tajimi JPN 103171 +1785 Ibb YEM 103300 +SELECT * FROM City USE INDEX () +WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 300 AND 600) AND +(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); +ID Name Country Population +1 Kabul AFG 1780000 +2 Qandahar AFG 237500 +3 Herat AFG 186800 +4 Mazar-e-Sharif AFG 127800 +7 Haag NLD 440900 +16 Haarlem NLD 148772 +25 Haarlemmermeer NLD 110722 +33 Willemstad ANT 2345 +34 Tirana ALB 270000 +55 Andorra la Vella AND 21189 +56 Luanda AGO 2022000 +57 Huambo AGO 163100 +58 Lobito AGO 130000 +59 Benguela AGO 128300 +60 Namibe AGO 118200 +61 South Hill AIA 961 +62 The Valley AIA 595 +64 Dubai ARE 669181 +65 Abu Dhabi ARE 398695 +66 Sharja ARE 320095 +67 al-Ayn ARE 225970 +68 Ajman ARE 114395 +129 Oranjestad ABW 29034 +191 Hamilton BMU 1200 +339 Passo Fundo BRA 166343 +364 Parnaíba BRA 129756 +372 Paranaguá BRA 126076 +379 Palmas BRA 121919 +386 Patos de Minas BRA 119262 +411 Guaratinguetá BRA 103433 +412 Cachoeirinha BRA 103240 +413 Codó BRA 103153 +424 Passos BRA 98570 +430 Paulo Afonso BRA 97291 +435 Parnamirim BRA 96210 +448 Patos BRA 90519 +451 Palhoça BRA 89465 +517 Oldham GBR 103931 +SELECT * FROM City +WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 300 AND 600) AND +(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); +ID Name Country Population +1 Kabul AFG 1780000 +2 Qandahar AFG 237500 +3 Herat AFG 186800 +4 Mazar-e-Sharif AFG 127800 +7 Haag NLD 440900 +16 Haarlem NLD 148772 +25 Haarlemmermeer NLD 110722 +33 Willemstad ANT 2345 +34 Tirana ALB 270000 +55 Andorra la Vella AND 21189 +56 Luanda AGO 2022000 +57 Huambo AGO 163100 +58 Lobito AGO 130000 +59 Benguela AGO 128300 +60 Namibe AGO 118200 +61 South Hill AIA 961 +62 The Valley AIA 595 +64 Dubai ARE 669181 +65 Abu Dhabi ARE 398695 +66 Sharja ARE 320095 +67 al-Ayn ARE 225970 +68 Ajman ARE 114395 +129 Oranjestad ABW 29034 +191 Hamilton BMU 1200 +339 Passo Fundo BRA 166343 +364 Parnaíba BRA 129756 +372 Paranaguá BRA 126076 +379 Palmas BRA 121919 +386 Patos de Minas BRA 119262 +411 Guaratinguetá BRA 103433 +412 Cachoeirinha BRA 103240 +413 Codó BRA 103153 +424 Passos BRA 98570 +430 Paulo Afonso BRA 97291 +435 Parnamirim BRA 96210 +448 Patos BRA 90519 +451 Palhoça BRA 89465 +517 Oldham GBR 103931 +EXPLAIN +SELECT * FROM City WHERE Population > 101000 AND Population < 102000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population Population 4 NULL 38 Using where +EXPLAIN +SELECT * FROM City WHERE Population > 101000 AND Population < 110000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population Population 4 NULL 327 Using where +EXPLAIN +SELECT * FROM City WHERE Country < 'C'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Country Country 3 NULL 446 Using where +EXPLAIN +SELECT * FROM City WHERE Country < 'AGO'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Country Country 3 NULL 5 Using where +EXPLAIN +SELECT * FROM City WHERE Name BETWEEN 'P' AND 'T'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ALL Name NULL NULL NULL 4249 Using where +EXPLAIN +SELECT * FROM City WHERE Name BETWEEN 'P' AND 'Pb'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 71 Using where +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 3400 AND 3800; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 944 Using where +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'P%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 235 Using where +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 102000) AND +(Country < 'C' OR Name BETWEEN 'P' AND 'T')) OR +((ID BETWEEN 3400 AND 3800) AND +(Country < 'AGO' OR Name LIKE 'Pa%')); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge PRIMARY,Population,Country,Name Country,Name,Population 3,35,4 NULL 114 Using sort_union(Country,Name,Population); Using where +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 110000) AND +(Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR +((ID BETWEEN 3790 AND 3800) AND +(Country < 'C' OR Name LIKE 'P%')); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge PRIMARY,Population,Country,Name Country,Name,PRIMARY 3,35,4 NULL 87 Using sort_union(Country,Name,PRIMARY); Using where +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 AND Population < 102000) AND +(Country < 'C' OR Name BETWEEN 'P' AND 'T')) OR +((ID BETWEEN 3400 AND 3800) AND +(Country < 'AGO' OR Name LIKE 'Pa%')); +ID Name Country Population +169 Naogaon BGD 101266 +205 Francistown BWA 101805 +417 Itaituba BRA 101320 +418 Araras BRA 101046 +751 Potchefstroom ZAF 101817 +1752 Sakata JPN 101651 +1851 Saint John´s CAN 101936 +1853 Saanich CAN 101388 +2909 Puno PER 101578 +3463 Pavlograd UKR 127000 +4030 Sandy USA 101853 +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 102000) AND +(Country < 'C' OR Name BETWEEN 'P' AND 'T')) OR +((ID BETWEEN 3400 AND 3800) AND +(Country < 'AGO' OR Name LIKE 'Pa%')); +ID Name Country Population +169 Naogaon BGD 101266 +205 Francistown BWA 101805 +417 Itaituba BRA 101320 +418 Araras BRA 101046 +751 Potchefstroom ZAF 101817 +1752 Sakata JPN 101651 +1851 Saint John´s CAN 101936 +1853 Saanich CAN 101388 +2909 Puno PER 101578 +3463 Pavlograd UKR 127000 +4030 Sandy USA 101853 +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 AND Population < 110000) AND +(Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR +((ID BETWEEN 3790 AND 3800) AND +(Country < 'C' OR Name LIKE 'P%')); +ID Name Country Population +168 Pabna BGD 103277 +189 Parakou BEN 103577 +750 Paarl ZAF 105768 +2865 Pak Pattan PAK 107800 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 110000) AND +(Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR +((ID BETWEEN 3790 AND 3800) AND +(Country < 'C' OR Name LIKE 'P%')); +ID Name Country Population +168 Pabna BGD 103277 +189 Parakou BEN 103577 +750 Paarl ZAF 105768 +2865 Pak Pattan PAK 107800 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +CREATE INDEX CountryPopulation ON City(Country,Population); +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'Pas%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 8 Using where +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'P%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 235 Using where +EXPLAIN +SELECT * FROM City WHERE (Population > 101000 AND Population < 103000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population Population 4 NULL 80 Using where +EXPLAIN +SELECT * FROM City WHERE Country='USA'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ref Country,CountryPopulation Country 3 const 274 Using where +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') +AND Country='USA'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge Population,Country,Name,CountryPopulation CountryPopulation,Name 7,35 NULL 17 Using sort_union(CountryPopulation,Name); Using where +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') +AND Country='USA'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ref Population,Country,Name,CountryPopulation Country 3 const 274 Using where +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') +AND Country='USA'; +ID Name Country Population +3943 Pasadena USA 141674 +3953 Pasadena USA 133936 +4023 Gary USA 102746 +4024 Berkeley USA 102743 +4025 Santa Clara USA 102361 +4026 Green Bay USA 102313 +4027 Cape Coral USA 102286 +4028 Arvada USA 102153 +4029 Pueblo USA 102121 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') +AND Country='USA'; +ID Name Country Population +3943 Pasadena USA 141674 +3953 Pasadena USA 133936 +4023 Gary USA 102746 +4024 Berkeley USA 102743 +4025 Santa Clara USA 102361 +4026 Green Bay USA 102313 +4027 Cape Coral USA 102286 +4028 Arvada USA 102153 +4029 Pueblo USA 102121 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') +AND Country='USA'; +ID Name Country Population +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3820 Portland USA 529121 +3844 Pittsburgh USA 334563 +3870 Plano USA 222030 +3912 Providence USA 173618 +3930 Pomona USA 149473 +3932 Paterson USA 149222 +3943 Pasadena USA 141674 +3951 Pembroke Pines USA 137427 +3953 Pasadena USA 133936 +3967 Paradise USA 124682 +3986 Palmdale USA 116670 +3996 Peoria USA 112936 +4007 Peoria USA 108364 +4016 Provo USA 105166 +4023 Gary USA 102746 +4024 Berkeley USA 102743 +4025 Santa Clara USA 102361 +4026 Green Bay USA 102313 +4027 Cape Coral USA 102286 +4028 Arvada USA 102153 +4029 Pueblo USA 102121 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +4035 Portsmouth USA 100565 +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') +AND Country='USA'; +ID Name Country Population +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3820 Portland USA 529121 +3844 Pittsburgh USA 334563 +3870 Plano USA 222030 +3912 Providence USA 173618 +3930 Pomona USA 149473 +3932 Paterson USA 149222 +3943 Pasadena USA 141674 +3951 Pembroke Pines USA 137427 +3953 Pasadena USA 133936 +3967 Paradise USA 124682 +3986 Palmdale USA 116670 +3996 Peoria USA 112936 +4007 Peoria USA 108364 +4016 Provo USA 105166 +4023 Gary USA 102746 +4024 Berkeley USA 102743 +4025 Santa Clara USA 102361 +4026 Green Bay USA 102313 +4027 Cape Coral USA 102286 +4028 Arvada USA 102153 +4029 Pueblo USA 102121 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +4035 Portsmouth USA 100565 +CREATE INDEX CountryName ON City(Country,Name); +EXPLAIN +SELECT * FROM City WHERE Country='USA'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 274 Using where +EXPLAIN +SELECT * FROM City WHERE Country='BRA'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 250 Using where +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 4025 AND 4035; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 4028 AND 4032; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 5 Using where +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 3500 AND 3800; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 300 Using where +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 4000 AND 4300; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 80 Using where +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 250 and 260 ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where +EXPLAIN +SELECT * FROM City WHERE (Population > 101000 AND Population < 102000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population Population 4 NULL 38 Using where +EXPLAIN +SELECT * FROM City WHERE (Population > 101000 AND Population < 103000); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population Population 4 NULL 80 Using where +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'Pa%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Name Name 35 NULL 71 Using where +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryPopulation,PRIMARY 7,4 NULL 13 Using sort_union(CountryPopulation,PRIMARY); Using where +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 103000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName,PRIMARY 38,4 NULL 10 Using sort_union(CountryName,PRIMARY); Using where +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 110000) OR +ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name BETWEEN 'P' AND 'T' OR ID BETWEEN 4000 AND 4300); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ref PRIMARY,Population,Country,Name,CountryPopulation,CountryName Country 3 const 274 Using where +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 AND Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); +ID Name Country Population +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); +ID Name Country Population +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 AND Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032); +ID Name Country Population +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032); +ID Name Country Population +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 AND Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); +ID Name Country Population +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); +ID Name Country Population +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 and Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryPopulation,CountryName,PRIMARY 7,38,4 NULL 35 Using sort_union(CountryPopulation,CountryName,PRIMARY); Using where +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 and Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA'; +ID Name Country Population +250 Mauá BRA 375055 +251 Carapicuíba BRA 357552 +252 Olinda BRA 354732 +253 Campina Grande BRA 352497 +254 São José do Rio Preto BRA 351944 +255 Caxias do Sul BRA 349581 +256 Moji das Cruzes BRA 339194 +257 Diadema BRA 335078 +258 Aparecida de Goiânia BRA 324662 +259 Piracicaba BRA 319104 +260 Cariacica BRA 319033 +285 Paulista BRA 248473 +339 Passo Fundo BRA 166343 +364 Parnaíba BRA 129756 +372 Paranaguá BRA 126076 +379 Palmas BRA 121919 +386 Patos de Minas BRA 119262 +424 Passos BRA 98570 +430 Paulo Afonso BRA 97291 +435 Parnamirim BRA 96210 +448 Patos BRA 90519 +451 Palhoça BRA 89465 +3793 New York USA 8008278 +3794 Los Angeles USA 3694820 +3795 Chicago USA 2896016 +3796 Houston USA 1953631 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3799 San Diego USA 1223400 +3800 Dallas USA 1188580 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City +WHERE ((Population > 101000 and Population < 102000) OR +ID BETWEEN 3790 AND 3800) AND Country='USA' + OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA'; +ID Name Country Population +285 Paulista BRA 248473 +339 Passo Fundo BRA 166343 +364 Parnaíba BRA 129756 +372 Paranaguá BRA 126076 +379 Palmas BRA 121919 +386 Patos de Minas BRA 119262 +424 Passos BRA 98570 +430 Paulo Afonso BRA 97291 +435 Parnamirim BRA 96210 +448 Patos BRA 90519 +451 Palhoça BRA 89465 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +250 Mauá BRA 375055 +251 Carapicuíba BRA 357552 +252 Olinda BRA 354732 +253 Campina Grande BRA 352497 +254 São José do Rio Preto BRA 351944 +255 Caxias do Sul BRA 349581 +256 Moji das Cruzes BRA 339194 +257 Diadema BRA 335078 +258 Aparecida de Goiânia BRA 324662 +259 Piracicaba BRA 319104 +260 Cariacica BRA 319033 +3793 New York USA 8008278 +3794 Los Angeles USA 3694820 +3795 Chicago USA 2896016 +3796 Houston USA 1953631 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3799 San Diego USA 1223400 +3800 Dallas USA 1188580 +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 11000) OR +ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName 38 NULL 18 Using where +EXPLAIN +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 11000) OR +ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country,Name,CountryPopulation,CountryName Name 35 NULL 1 Using where +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 AND Population < 11000) OR +ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300); +ID Name Country Population +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 11000) OR +ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300); +ID Name Country Population +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +SELECT * FROM City USE INDEX () +WHERE ((Population > 101000 AND Population < 11000) OR +ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300); +ID Name Country Population +3798 Phoenix USA 1321045 +SELECT * FROM City +WHERE ((Population > 101000 AND Population < 11000) OR +ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300); +ID Name Country Population +3798 Phoenix USA 1321045 +DROP DATABASE world; +use test; +CREATE TABLE t1 ( +id int(10) unsigned NOT NULL auto_increment, +account_id int(10) unsigned NOT NULL, +first_name varchar(50) default NULL, +middle_name varchar(50) default NULL, +last_name varchar(100) default NULL, +home_address_1 varchar(150) default NULL, +home_city varchar(75) default NULL, +home_state char(2) default NULL, +home_postal_code varchar(50) default NULL, +home_county varchar(75) default NULL, +home_country char(3) default NULL, +work_address_1 varchar(150) default NULL, +work_city varchar(75) default NULL, +work_state char(2) default NULL, +work_postal_code varchar(50) default NULL, +work_county varchar(75) default NULL, +work_country char(3) default NULL, +login varchar(50) NOT NULL, +PRIMARY KEY (id), +KEY login (login,account_id), +KEY account_id (account_id), +KEY user_home_country_indx (home_country), +KEY user_work_country_indx (work_country), +KEY user_home_state_indx (home_state), +KEY user_work_state_indx (work_state), +KEY user_home_city_indx (home_city), +KEY user_work_city_indx (work_city), +KEY user_first_name_indx (first_name), +KEY user_last_name_indx (last_name) +); +insert into t1(account_id, login, home_state, work_state) values +(1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'), +(1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'); +insert into t1(account_id, login, home_state, work_state) +select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) +select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) +select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) +select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) +select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) +select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) +select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) +select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) +select 1, 'pw', 'ak', 'ak' from t1; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +select count(*) from t1 where account_id = 1; +count(*) +3072 +select * from t1 +where (home_state = 'ia' or work_state='ia') and account_id = 1; +id account_id first_name middle_name last_name home_address_1 home_city home_state home_postal_code home_county home_country work_address_1 work_city work_state work_postal_code work_county work_country login +1 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw +2 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw +3 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw +4 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw +5 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw +6 1 NULL NULL NULL NULL NULL ia NULL NULL NULL NULL NULL ia NULL NULL NULL pw +explain +select * from t1 +where (home_state = 'ia' or work_state='ia') and account_id = 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge account_id,user_home_state_indx,user_work_state_indx user_home_state_indx,user_work_state_indx 3,3 NULL 10 Using union(user_home_state_indx,user_work_state_indx); Using where +drop table t1; +CREATE TABLE t1 ( +c1 int(11) NOT NULL auto_increment, +c2 decimal(10,0) default NULL, +c3 decimal(10,0) default NULL, +c4 decimal(10,0) default NULL, +c5 decimal(10,0) default NULL, +cp decimal(1,0) default NULL, +ce decimal(10,0) default NULL, +cdata char(20), +PRIMARY KEY (c1), +KEY k1 (c2,c3,cp,ce), +KEY k2 (c4,c5,cp,ce) +); +insert into t1 (c2, c3, c4, c5, cp) values(1,1,1,1,1); +insert into t1 (c2, c3, c4, c5, cp) values(2,1,1,1,4); +insert into t1 (c2, c3, c4, c5, cp) values(2,1,2,1,1); +insert into t1 (c2, c3, c4, c5, cp) values(2,1,3,1,4); +insert into t1 (c2, c3, c4, c5, cp) values(3,1,4,1,4); +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) +select c2, c3, c4, c5, cp from t1 where cp = 4; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +explain +select * from t1 where (c2=1 and c3=1) or (c4=2 and c5=1); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge k1,k2 k1,k2 12,12 NULL 2 Using sort_union(k1,k2); Using where +explain +select * from t1 +where (c2=1 and c3=1 and cp=1) or (c4=2 and c5=1 and cp=1); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge k1,k2 k1,k2 14,14 NULL 2 Using sort_union(k1,k2); Using where +explain +select * from t1 +where ((c2=1 and c3=1) or (c4=2 and c5=1)) and cp=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge k1,k2 k1,k2 14,14 NULL 2 Using sort_union(k1,k2); Using where +select * from t1 +where (c2=1 and c3=1 and cp=1) or (c4=2 and c5=1 and cp=1); +c1 c2 c3 c4 c5 cp ce cdata +1 1 1 1 1 1 NULL NULL +3 2 1 2 1 1 NULL NULL +select * from t1 +where ((c2=1 and c3=1) or (c4=2 and c5=1)) and cp=1; +c1 c2 c3 c4 c5 cp ce cdata +1 1 1 1 1 1 NULL NULL +3 2 1 2 1 1 NULL NULL +drop table t1; +create table t1 ( +c1 int auto_increment primary key, +c2 char(20), +c3 char (20), +c4 int +); +alter table t1 add key k1 (c2); +alter table t1 add key k2 (c3); +alter table t1 add key k3 (c4); +insert into t1 values(null, 'a', 'b', 0); +insert into t1 values(null, 'c', 'b', 0); +insert into t1 values(null, 'a', 'd', 0); +insert into t1 values(null, 'ccc', 'qqq', 0); +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3,c4) select c2,c3,1 from t1 where c2 != 'a'; +insert into t1 (c2,c3,c4) select c2,c3,2 from t1 where c2 != 'a'; +insert into t1 (c2,c3,c4) select c2,c3,3 from t1 where c2 != 'a'; +insert into t1 (c2,c3,c4) select c2,c3,4 from t1 where c2 != 'a'; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +select count(*) from t1 where (c2='e' OR c3='q'); +count(*) +0 +select count(*) from t1 where c4 != 0; +count(*) +3840 +explain +select distinct c1 from t1 where (c2='e' OR c3='q'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge k1,k2 k1,k2 21,21 NULL 2 Using union(k1,k2); Using where +explain +select distinct c1 from t1 where (c4!= 0) AND (c2='e' OR c3='q'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge k1,k2,k3 k1,k2 21,21 NULL 2 Using union(k1,k2); Using where +drop table t1; +create table t1 ( +id int unsigned auto_increment primary key, +c1 char(12), +c2 char(15), +c3 char(1) +); +insert into t1 (c3) values ('1'), ('2'); +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +update t1 set c1=lpad(id+1000, 12, ' '), c2=lpad(id+10000, 15, ' '); +alter table t1 add unique index (c1), add unique index (c2), add index (c3); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +explain +select * from t1 where (c1=' 100000' or c2=' 2000000'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge c1,c2 c1,c2 13,16 NULL 2 Using union(c1,c2); Using where +explain +select * from t1 where (c1=' 100000' or c2=' 2000000') and c3='2'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge c1,c2,c3 c1,c2 13,16 NULL 2 Using union(c1,c2); Using where +select * from t1 where (c1=' 100000' or c2=' 2000000'); +id c1 c2 c3 +select * from t1 where (c1=' 100000' or c2=' 2000000') and c3='2'; +id c1 c2 c3 +drop table t1; +SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/t/range_vs_index_merge.test b/mysql-test/t/range_vs_index_merge.test new file mode 100755 index 00000000000..a4511ccfd19 --- /dev/null +++ b/mysql-test/t/range_vs_index_merge.test @@ -0,0 +1,805 @@ +--disable_warnings +DROP TABLE IF EXISTS t1,t2,t3,t4; +DROP DATABASE IF EXISTS world; +--enable_warnings + +set names utf8; + +CREATE DATABASE world; + +use world; + +--source include/world_schema.inc + +--disable_query_log +--disable_result_log +--disable_warnings +--source include/world.inc +--enable_warnings +--enable_result_log +--enable_query_log + +SELECT COUNT(*) FROM Country; +SELECT COUNT(*) FROM City; +SELECT COUNT(*) FROM CountryLanguage; + +CREATE INDEX Name ON City(Name); + +--disable_query_log +--disable_result_log +--disable_warnings +ANALYZE TABLE City; +--enable_warnings +--enable_result_log +--enable_query_log + +# The following 4 queries are added for code coverage + +EXPLAIN +SELECT * FROM City + WHERE (Population >= 100000 OR Name LIKE 'P%' OR Population < 100000); + +EXPLAIN +SELECT * FROM City + WHERE (Population >= 100000 OR Name LIKE 'P%') AND Country='CAN' OR + (Population < 100000 OR Name Like 'T%') AND Country='ARG'; + +EXPLAIN +SELECT * FROM City + WHERE Population < 200000 AND Name LIKE 'P%' AND + (Population > 300000 OR Name LIKE 'T%') AND + (Population < 100000 OR Name LIKE 'Pa%'); + +EXPLAIN +SELECT * FROM City + WHERE Population > 100000 AND Name LIKE 'Aba%' OR + Country IN ('CAN', 'ARG') AND ID < 3800 OR + Country < 'U' AND Name LIKE 'Zhu%' OR + ID BETWEEN 3800 AND 3810; + +# The output of the next 3 commands tells us about selectivities +# of the conditions utilized in 2 queries following after them + +EXPLAIN +SELECT * FROM City + WHERE (Population > 101000 AND Population < 115000); + +EXPLAIN +SELECT * FROM City + WHERE (Population > 101000 AND Population < 103000); + +EXPLAIN +SELECT * FROM City + WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')); + +# The pattern of the WHERE condition used in the following 2 queries is +# (range(key1) OR range(key2)) AND range(key3) +# Varying values of the constants in the second conjunct of the condition +# we can get either a plan with range index scan for key3 or a plan with +# an index merge retrieval over key2 and key3 + +EXPLAIN +SELECT * FROM City + WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) + AND (Population > 101000 AND Population < 115000); + +EXPLAIN +SELECT * FROM City + WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) + AND (Population > 101000 AND Population < 103000); + +# The following 4 queries check that the plans +# for the previous 2 plans are valid + +SELECT * FROM City USE INDEX () + WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) + AND (Population > 101000 AND Population < 115000); + +SELECT * FROM City + WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) + AND (Population > 101000 AND Population < 115000); + +SELECT * FROM City USE INDEX () + WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) + AND (Population > 101000 AND Population < 103000); + +SELECT * FROM City + WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) + AND (Population > 101000 AND Population < 103000); + +# The output of the next 7 commands tells us about selectivities +# of the conditions utilized in 4 queries following after them + +EXPLAIN +SELECT * FROM City WHERE (Name < 'Ac'); +EXPLAIN +SELECT * FROM City WHERE (Name < 'C'); +EXPLAIN +SELECT * FROM City WHERE (Country > 'A' AND Country < 'B'); +EXPLAIN +SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'Pb'); +EXPLAIN +SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'T'); +EXPLAIN +SELECT * FROM City WHERE (Population > 101000 AND Population < 110000); +EXPLAIN +SELECT * FROM City WHERE (Population > 103000 AND Population < 104000); + +# The pattern of the WHERE condition used in the following 4 queries is +# (range1(key1) AND range(key2)) OR (range2(key1) AND range(key3) +# Varying values of the constants in the range conjuncts of the condition +# we can get: +# 1. a plan with range index over key1 +# index merge retrievals over: +# 2. key1 and key3 +# 3. key2 and key1 +# 4. key2 and key3 + +EXPLAIN +SELECT * FROM City + WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); + +EXPLAIN +SELECT * FROM City + WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); + +EXPLAIN +SELECT * FROM City + WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); + +EXPLAIN +SELECT * FROM City + WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); + +# The following 8 queries check that the plans +# for the previous 4 plans are valid + +SELECT * FROM City USE INDEX () + WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); + +SELECT * FROM City + WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); + +SELECT * FROM City USE INDEX () + WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); + +SELECT * FROM City + WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); + +SELECT * FROM City USE INDEX () + WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); + +SELECT * FROM City + WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); + +SELECT * FROM City USE INDEX () + WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); + +SELECT * FROM City + WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); + + +# The output of the next 6 commands tells us about selectivities +# of the conditions utilized in 3 queries following after them + +EXPLAIN +SELECT * FROM City WHERE (ID < 50) OR (ID BETWEEN 100 AND 110); +EXPLAIN +SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 300 AND 600); +EXPLAIN +SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1800); +EXPLAIN +SELECT * FROM City WHERE Country > 'A' AND Country < 'ARG'; +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'H%' OR Name LIKE 'P%' ; +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'Ha%' OR Name LIKE 'Pa%' ; + +# The pattern of the WHERE condition used in the following 3 queries is +# (range1(key1) AND (range1(key2) OR range(key3)) OR +# (range2(key1) AND (range2(key2) OR range(key4)) +# Varying values of the constants in the range predicates of the condition +# we can get: +# 1. a plan with range index over key1 +# 2. an index merge retrieval over key1, key2 and key3 + +EXPLAIN +SELECT * FROM City + WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 100 AND 110) AND + (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); + +EXPLAIN +SELECT * FROM City + WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 900 AND 1800) AND + (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); + +EXPLAIN +SELECT * FROM City + WHERE ((ID < 600) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 300 AND 600) AND + (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); + + +# The following 6 queries check that the plans +# for the previous 3 plans are valid + +SELECT * FROM City USE INDEX () + WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 100 AND 110) AND + (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); + +SELECT * FROM City + WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 100 AND 110) AND + (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); + +SELECT * FROM City USE INDEX() + WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 900 AND 1800) AND + (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); + +SELECT * FROM City + WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 900 AND 1800) AND + (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); + +SELECT * FROM City USE INDEX () + WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 300 AND 600) AND + (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); + +SELECT * FROM City + WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 300 AND 600) AND + (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); + + +# The output of the next 8 commands tells us about selectivities +# of the conditions utilized in 2 queries following after them + +EXPLAIN +SELECT * FROM City WHERE Population > 101000 AND Population < 102000; +EXPLAIN +SELECT * FROM City WHERE Population > 101000 AND Population < 110000; +EXPLAIN +SELECT * FROM City WHERE Country < 'C'; +EXPLAIN +SELECT * FROM City WHERE Country < 'AGO'; +EXPLAIN +SELECT * FROM City WHERE Name BETWEEN 'P' AND 'T'; +EXPLAIN +SELECT * FROM City WHERE Name BETWEEN 'P' AND 'Pb'; +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 3400 AND 3800; +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800; +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'P%'; + +# The pattern of the WHERE condition used in the following 2 queries is +# (range(key1) AND (range1(key2) OR range1(key3)) OR +# (range(key4) AND (range2(key2) OR range2(key3)) +# Varying values of the constants in the range predicates of the condition +# we can get: +# index merge retrievals over: +# 1. key1, key2 and key3 +# 2. key4, key2 and key3 + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 102000) AND + (Country < 'C' OR Name BETWEEN 'P' AND 'T')) OR + ((ID BETWEEN 3400 AND 3800) AND + (Country < 'AGO' OR Name LIKE 'Pa%')); + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 110000) AND + (Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR + ((ID BETWEEN 3790 AND 3800) AND + (Country < 'C' OR Name LIKE 'P%')); + +# The following 4 queries check that the plans +# for the previous 2 plans are valid + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 AND Population < 102000) AND + (Country < 'C' OR Name BETWEEN 'P' AND 'T')) OR + ((ID BETWEEN 3400 AND 3800) AND + (Country < 'AGO' OR Name LIKE 'Pa%')); + +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 102000) AND + (Country < 'C' OR Name BETWEEN 'P' AND 'T')) OR + ((ID BETWEEN 3400 AND 3800) AND + (Country < 'AGO' OR Name LIKE 'Pa%')); + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 AND Population < 110000) AND + (Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR + ((ID BETWEEN 3790 AND 3800) AND + (Country < 'C' OR Name LIKE 'P%')); + +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 110000) AND + (Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR + ((ID BETWEEN 3790 AND 3800) AND + (Country < 'C' OR Name LIKE 'P%')); + + +CREATE INDEX CountryPopulation ON City(Country,Population); + +--disable_query_log +--disable_result_log +--disable_warnings +ANALYZE TABLE City; +--enable_warnings +--enable_result_log +--enable_query_log + +# The output of the next 4 commands tells us about selectivities +# of the conditions utilized in 2 queries following after them + +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'Pas%'; +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'P%'; +EXPLAIN +SELECT * FROM City WHERE (Population > 101000 AND Population < 103000); +EXPLAIN +SELECT * FROM City WHERE Country='USA'; + +# The pattern of the WHERE condition used in the following 3 queries is +# (range(key1_p2) OR (range(key2)) AND key1_p1=c +# Varying values of the constants in the range predicates of the condition +# we can get: +# 1. a plan with range index over key1_p1 +# 2. an index merge retrieval over: key1 and key2 + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') + AND Country='USA'; + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') + AND Country='USA'; + +# The following 4 queries check that the plans +# for the previous 2 plans are valid + +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') + AND Country='USA'; + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') + AND Country='USA'; + +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') + AND Country='USA'; + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') + AND Country='USA'; + + +CREATE INDEX CountryName ON City(Country,Name); + +--disable_query_log +--disable_result_log +--disable_warnings +ANALYZE TABLE City; +--enable_warnings +--enable_result_log +--enable_query_log + +# The output of the next 11 commands tells us about selectivities +# of the conditions utilized in 3 queries following after them + +EXPLAIN +SELECT * FROM City WHERE Country='USA'; +EXPLAIN +SELECT * FROM City WHERE Country='BRA'; +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800; +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 4025 AND 4035; +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 4028 AND 4032; +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 3500 AND 3800; +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 4000 AND 4300; +EXPLAIN +SELECT * FROM City WHERE ID BETWEEN 250 and 260 ; +EXPLAIN +SELECT * FROM City WHERE (Population > 101000 AND Population < 102000); +EXPLAIN +SELECT * FROM City WHERE (Population > 101000 AND Population < 103000); +EXPLAIN +SELECT * FROM City WHERE Name LIKE 'Pa%'; + +# The pattern of the WHERE condition used in the following 3 queries is +# (range(key1_p2) OR range1(key3)) AND +# range(key1|2_p1=c) AND +# (range(key2_p2) OR range2(key3)) +# Varying values of the constants in the range conjuncts of the condition +# we can get: +# 1. a plan with range index over key1|2_p1 +# index merge retrievals over: +# 2. key1 and key3 +# 3. key2 and key3 + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 103000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032); + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 110000) OR + ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name BETWEEN 'P' AND 'T' OR ID BETWEEN 4000 AND 4300); + +# The following 6 queries check that the plans +# for the previous 3 plans are valid + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 AND Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); + +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 AND Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032); + +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032); + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 AND Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); + +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); + + +# The pattern of the WHERE condition used in the following query is +# (range(key1_p2) OR range1(key3)) AND range(key1|2_p1=c1) AND +# (range(key2_p2) OR range1(key3)) AND range(key1|2_p1=c2) +# We get an index merge retrieval over key1, key2 and key3 for it + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 and Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA'; + +# The following 2 queries check that the plans +# for the previous plan is valid + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 and Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA'; + +SELECT * FROM City + WHERE ((Population > 101000 and Population < 102000) OR + ID BETWEEN 3790 AND 3800) AND Country='USA' + OR (Name LIKE 'Pa%' OR ID BETWEEN 250 AND 260) AND Country='BRA'; + +# The pattern of the WHERE condition used in the following query is +# (impossible_range(key1_p2) OR range1(key3)) AND +# range(key1|2_p1=c1) AND +# (range(key2_p2) OR range2(key3)) +# where range1(key3) and range2(key3) are disjoint +# Varying values of the constant in range predicates we get plans: +# 1. with an index scan over key2 +# 2. with an index scan over key4=key2_p2 + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 11000) OR + ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300); + +EXPLAIN +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 11000) OR + ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300); + +# The following 4 queries check that the plans +# for the previous 2 plans are valid + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 AND Population < 11000) OR + ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300); + +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 11000) OR + ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'P%' OR ID BETWEEN 4000 AND 4300); + +SELECT * FROM City USE INDEX () + WHERE ((Population > 101000 AND Population < 11000) OR + ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300); + +SELECT * FROM City + WHERE ((Population > 101000 AND Population < 11000) OR + ID BETWEEN 3500 AND 3800) AND Country='USA' + AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300); + + +DROP DATABASE world; + +use test; + +# +# Bug #17259: a bad range scan and a good index merge plan +# + +CREATE TABLE t1 ( + id int(10) unsigned NOT NULL auto_increment, + account_id int(10) unsigned NOT NULL, + first_name varchar(50) default NULL, + middle_name varchar(50) default NULL, + last_name varchar(100) default NULL, + home_address_1 varchar(150) default NULL, + home_city varchar(75) default NULL, + home_state char(2) default NULL, + home_postal_code varchar(50) default NULL, + home_county varchar(75) default NULL, + home_country char(3) default NULL, + work_address_1 varchar(150) default NULL, + work_city varchar(75) default NULL, + work_state char(2) default NULL, + work_postal_code varchar(50) default NULL, + work_county varchar(75) default NULL, + work_country char(3) default NULL, + login varchar(50) NOT NULL, + PRIMARY KEY (id), + KEY login (login,account_id), + KEY account_id (account_id), + KEY user_home_country_indx (home_country), + KEY user_work_country_indx (work_country), + KEY user_home_state_indx (home_state), + KEY user_work_state_indx (work_state), + KEY user_home_city_indx (home_city), + KEY user_work_city_indx (work_city), + KEY user_first_name_indx (first_name), + KEY user_last_name_indx (last_name) +); + +insert into t1(account_id, login, home_state, work_state) values + (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'), + (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'), (1, 'pw', 'ia', 'ia'); +insert into t1(account_id, login, home_state, work_state) + select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) + select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) + select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) + select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) + select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) + select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) + select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) + select 1, 'pw', 'ak', 'ak' from t1; +insert into t1(account_id, login, home_state, work_state) + select 1, 'pw', 'ak', 'ak' from t1; + +analyze table t1; + +select count(*) from t1 where account_id = 1; + +select * from t1 + where (home_state = 'ia' or work_state='ia') and account_id = 1; + +explain +select * from t1 + where (home_state = 'ia' or work_state='ia') and account_id = 1; + +drop table t1; + +# +# Bug #17673: no index merge plan if the condition for the last used +# index component is factored out of the or formula +# + +CREATE TABLE t1 ( + c1 int(11) NOT NULL auto_increment, + c2 decimal(10,0) default NULL, + c3 decimal(10,0) default NULL, + c4 decimal(10,0) default NULL, + c5 decimal(10,0) default NULL, + cp decimal(1,0) default NULL, + ce decimal(10,0) default NULL, + cdata char(20), + PRIMARY KEY (c1), + KEY k1 (c2,c3,cp,ce), + KEY k2 (c4,c5,cp,ce) +); + +insert into t1 (c2, c3, c4, c5, cp) values(1,1,1,1,1); +insert into t1 (c2, c3, c4, c5, cp) values(2,1,1,1,4); +insert into t1 (c2, c3, c4, c5, cp) values(2,1,2,1,1); +insert into t1 (c2, c3, c4, c5, cp) values(2,1,3,1,4); +insert into t1 (c2, c3, c4, c5, cp) values(3,1,4,1,4); + +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; +insert into t1 (c2, c3, c4, c5, cp) + select c2, c3, c4, c5, cp from t1 where cp = 4; + +analyze table t1; + +explain + select * from t1 where (c2=1 and c3=1) or (c4=2 and c5=1); + +explain + select * from t1 + where (c2=1 and c3=1 and cp=1) or (c4=2 and c5=1 and cp=1); + +explain + select * from t1 + where ((c2=1 and c3=1) or (c4=2 and c5=1)) and cp=1; + +select * from t1 + where (c2=1 and c3=1 and cp=1) or (c4=2 and c5=1 and cp=1); + +select * from t1 + where ((c2=1 and c3=1) or (c4=2 and c5=1)) and cp=1; + +drop table t1; + +# +# Bug #23322: a bad range scan and a good index merge plan +# + +create table t1 ( + c1 int auto_increment primary key, + c2 char(20), + c3 char (20), + c4 int +); +alter table t1 add key k1 (c2); +alter table t1 add key k2 (c3); +alter table t1 add key k3 (c4); + +insert into t1 values(null, 'a', 'b', 0); +insert into t1 values(null, 'c', 'b', 0); +insert into t1 values(null, 'a', 'd', 0); +insert into t1 values(null, 'ccc', 'qqq', 0); + +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; +insert into t1 (c2,c3) select c2,c3 from t1 where c2 != 'a'; + +insert into t1 (c2,c3,c4) select c2,c3,1 from t1 where c2 != 'a'; +insert into t1 (c2,c3,c4) select c2,c3,2 from t1 where c2 != 'a'; +insert into t1 (c2,c3,c4) select c2,c3,3 from t1 where c2 != 'a'; +insert into t1 (c2,c3,c4) select c2,c3,4 from t1 where c2 != 'a'; + +analyze table t1; + +select count(*) from t1 where (c2='e' OR c3='q'); +select count(*) from t1 where c4 != 0; + +explain + select distinct c1 from t1 where (c2='e' OR c3='q'); + +explain + select distinct c1 from t1 where (c4!= 0) AND (c2='e' OR c3='q'); + +drop table t1; + +# +# Bug #30151: a bad range scan and a good index merge plan +# + +create table t1 ( + id int unsigned auto_increment primary key, + c1 char(12), + c2 char(15), + c3 char(1) +); + +insert into t1 (c3) values ('1'), ('2'); + +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; +insert into t1 (c3) select c3 from t1; + +update t1 set c1=lpad(id+1000, 12, ' '), c2=lpad(id+10000, 15, ' '); + +alter table t1 add unique index (c1), add unique index (c2), add index (c3); + +analyze table t1; + +explain + select * from t1 where (c1=' 100000' or c2=' 2000000'); +explain + select * from t1 where (c1=' 100000' or c2=' 2000000') and c3='2'; + +select * from t1 where (c1=' 100000' or c2=' 2000000'); +select * from t1 where (c1=' 100000' or c2=' 2000000') and c3='2'; + +drop table t1; + + + + + diff --git a/mysql-test/t/range_vs_index_merge_innodb.test b/mysql-test/t/range_vs_index_merge_innodb.test new file mode 100755 index 00000000000..e85cd044ece --- /dev/null +++ b/mysql-test/t/range_vs_index_merge_innodb.test @@ -0,0 +1,7 @@ +--source include/have_innodb.inc + +SET SESSION STORAGE_ENGINE='InnoDB'; + +--source t/range_vs_index_merge.test + +SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 0d7d7253f08..082bacc4810 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -497,6 +497,11 @@ public: pos->increment_use_count(count); } } + void incr_refs() + { + increment_use_count(1); + use_count++; + } void free_tree() { for (SEL_ARG *pos=first(); pos ; pos=pos->next) @@ -558,7 +563,100 @@ public: class SEL_IMERGE; +#define CLONE_KEY1_MAYBE 1 +#define CLONE_KEY2_MAYBE 2 +#define swap_clone_flag(A) ((A & 1) << 1) | ((A & 2) >> 1) + +/* + While objects of the class SEL_ARG represent ranges for indexes or + index infixes (including ranges for index prefixes and index suffixes), + objects of the class SEL_TREE represent AND/OR formulas of such ranges. + Currently an AND/OR formula represented by a SEL_TREE object can have + at most three levels: + + ::= + [ AND ] + [ [ AND ...] ] + + ::= + [ AND ... ] + + ::= + [ OR ] + + As we can see from the above definitions: + - SEL_RANGE_TREE formula is a conjunction of SEL_ARG formulas + - SEL_IMERGE formula is a disjunction of SEL_RANGE_TREE formulas + - SEL_TREE formula is a conjunction of a SEL_RANGE_TREE formula + and SEL_IMERGE formulas. + It's required above that a SEL_TREE formula has at least one conjunct. + + Usually we will consider normalized SEL_RANGE_TREE formulas where we use + TRUE as conjunct members for those indexes whose SEL_ARG trees are empty. + + We will call an SEL_TREE object simply 'tree'. + The part of a tree that represents SEL_RANGE_TREE formula is called + 'range part' of the tree while the remaining part is called 'imerge part'. + If a tree contains only a range part then we call such a tree 'range tree'. + Components of a range tree that represent SEL_ARG formulas are called ranges. + If a tree does not contain any range part we call such a tree 'imerge tree'. + Components of the imerge part of a tree that represent SEL_IMERGE formula + are called imerges. + + Usually we'll designate: + SEL_TREE formulas by T_1,...,T_k + SEL_ARG formulas by R_1,...,R_k + SEL_RANGE_TREE formulas by RT_1,...,RT_k + SEL_IMERGE formulas by M_1,...,M_k + Accordingly we'll use: + t_1,...,t_k - to designate trees representing T_1,...,T_k + r_1,...,r_k - to designate ranges representing R_1,...,R_k + rt_1,...,r_tk - to designate range trees representing RT_1,...,RT_k + m_1,...,m_k - to designate imerges representing M_1,...,M_k + + SEL_TREE objects are usually built from WHERE conditions or + ON expressions. + A SEL_TREE object always represents an inference of the condition it is + built from. Therefore, if a row satisfies a SEL_TREE formula it also + satisfies the condition it is built from. + + The following transformations of tree t representing SEL_TREE formula T + yield a new tree t1 thar represents an inference of T: T=>T1. + (1) remove any of SEL_ARG tree from the range part of t + (2) remove any imerge from the tree t + (3) remove any of SEL_ARG tree from any range tree contained + in any imerge of tree + + Since the basic blocks of any SEL_TREE objects are ranges, SEL_TREE + objects in many cases can be effectively used to filter out a big part + of table rows that do not satisfy WHERE/IN conditions utilizing + only single or multiple range index scans. + + A single range index scan is constructed for a range tree that contains + only one SEL_ARG object for an index or an index prefix. + An index intersection scan can be constructed for a range tree + that contains several SEL_ARG objects. Currently index intersection + scans are constructed only for single-point ranges. + An index merge scan is constructed for a imerge tree that contains only + one imerge. If range trees of this imerge contain only single-point merges + than a union of index intersections can be built. + + Usually the tree built by the range optimizer for a query table contains + more than one range in the range part, and additionally may contain some + imerges in the imerge part. The range optimizer evaluates all of them one + by one and chooses the range or the imerge that provides the cheapest + single or multiple range index scan of the table. According to rules + (1)-(3) this scan always filter out only those rows that do not satisfy + the query conditions. + + For any condition the SEL_TREE object for it is built in a bottom up + manner starting from the range trees for the predicates. The tree_and + function builds a tree for any conjunction of formulas from the trees + for its conjuncts. The tree_or function builds a tree for any disjunction + of formulas from the trees for its disjuncts. +*/ + class SEL_TREE :public Sql_alloc { public: @@ -574,7 +672,7 @@ public: keys_map.clear_all(); bzero((char*) keys,sizeof(keys)); } - SEL_TREE(SEL_TREE *arg, RANGE_OPT_PARAM *param); + SEL_TREE(SEL_TREE *arg, bool without_merges, RANGE_OPT_PARAM *param); /* Note: there may exist SEL_TREE objects with sel_tree->type=KEY and keys[i]=0 for all i. (SergeyP: it is not clear whether there is any @@ -597,6 +695,9 @@ public: struct st_ror_scan_info **ror_scans; /* list of ROR key scans */ struct st_ror_scan_info **ror_scans_end; /* last ROR scan */ /* Note that #records for each key scan is stored in table->quick_rows */ + + bool without_ranges() { return keys_map.is_clear_all(); } + bool without_imerges() { return merges.is_empty(); } }; class RANGE_OPT_PARAM @@ -642,6 +743,7 @@ class PARAM : public RANGE_OPT_PARAM { public: KEY_PART *key[MAX_KEY]; /* First key parts of keys used in the query */ + ha_rows quick_rows[MAX_KEY]; longlong baseflag; uint max_key_part, range_count; @@ -669,7 +771,7 @@ class TABLE_READ_PLAN; class TRP_RANGE; class TRP_ROR_INTERSECT; class TRP_ROR_UNION; - class TRP_ROR_INDEX_MERGE; + class TRP_INDEX_MERGE; class TRP_GROUP_MIN_MAX; struct st_ror_scan_info; @@ -708,6 +810,10 @@ static TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, double read_time); static +TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge, + TRP_INDEX_MERGE *imerge_trp, + double read_time); +static TRP_GROUP_MIN_MAX *get_best_group_min_max(PARAM *param, SEL_TREE *tree); static double get_index_only_read_time(const PARAM* param, ha_rows records, int keynr); @@ -721,11 +827,15 @@ static void print_ror_scans_arr(TABLE *table, const char *msg, static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg); #endif -static SEL_TREE *tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2); -static SEL_TREE *tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2); +static SEL_TREE *tree_and(RANGE_OPT_PARAM *param, + SEL_TREE *tree1, SEL_TREE *tree2); +static SEL_TREE *tree_or(RANGE_OPT_PARAM *param, + SEL_TREE *tree1,SEL_TREE *tree2); static SEL_ARG *sel_add(SEL_ARG *key1,SEL_ARG *key2); -static SEL_ARG *key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2); -static SEL_ARG *key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, +static SEL_ARG *key_or(RANGE_OPT_PARAM *param, + SEL_ARG *key1, SEL_ARG *key2); +static SEL_ARG *key_and(RANGE_OPT_PARAM *param, + SEL_ARG *key1, SEL_ARG *key2, uint clone_flag); static bool get_range(SEL_ARG **e1,SEL_ARG **e2,SEL_ARG *root1); bool get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key, @@ -736,21 +846,23 @@ static bool eq_tree(SEL_ARG* a,SEL_ARG *b); static SEL_ARG null_element(SEL_ARG::IMPOSSIBLE); static bool null_part_in_key(KEY_PART *key_part, const uchar *key, uint length); -bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, RANGE_OPT_PARAM* param); +static bool sel_trees_have_common_keys(RANGE_OPT_PARAM* param, + SEL_TREE *tree1, SEL_TREE *tree2, + key_map *common_keys); +static void eliminate_single_tree_imerges(RANGE_OPT_PARAM *param, + SEL_TREE *tree); +static bool sel_trees_can_be_ored(RANGE_OPT_PARAM* param, + SEL_TREE *tree1, SEL_TREE *tree2, + key_map *common_keys); +static bool sel_trees_must_be_ored(RANGE_OPT_PARAM* param, + SEL_TREE *tree1, SEL_TREE *tree2, + key_map common_keys); +static int and_range_trees(RANGE_OPT_PARAM *param, + SEL_TREE *tree1, SEL_TREE *tree2, + SEL_TREE *result); +static bool remove_nonrange_trees(RANGE_OPT_PARAM *param, SEL_TREE *tree); -/* - SEL_IMERGE is a list of possible ways to do index merge, i.e. it is - a condition in the following form: - (t_1||t_2||...||t_N) && (next) - - where all t_i are SEL_TREEs, next is another SEL_IMERGE and no pair - (t_i,t_j) contains SEL_ARGS for the same index. - - SEL_TREE contained in SEL_IMERGE always has merges=NULL. - - This class relies on memory manager to do the cleanup. -*/ class SEL_IMERGE : public Sql_alloc { @@ -768,23 +880,37 @@ public: trees_next(trees), trees_end(trees + PREALLOCED_TREES) {} - SEL_IMERGE (SEL_IMERGE *arg, RANGE_OPT_PARAM *param); + SEL_IMERGE (SEL_IMERGE *arg, uint cnt, RANGE_OPT_PARAM *param); int or_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree); - int or_sel_tree_with_checks(RANGE_OPT_PARAM *param, SEL_TREE *new_tree); - int or_sel_imerge_with_checks(RANGE_OPT_PARAM *param, SEL_IMERGE* imerge); + bool have_common_keys(RANGE_OPT_PARAM *param, SEL_TREE *tree); + int and_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree, + SEL_IMERGE *new_imerge); + int or_sel_tree_with_checks(RANGE_OPT_PARAM *param, + SEL_TREE *new_tree, + bool is_first_check_pass, + bool *is_last_check_pass); + int or_sel_imerge_with_checks(RANGE_OPT_PARAM *param, + SEL_IMERGE* imerge, + bool is_first_check_pass, + bool *is_last_check_pass); }; /* - Add SEL_TREE to this index_merge without any checks, + Add a range tree to the range trees of this imerge - NOTES - This function implements the following: - (x_1||...||x_N) || t = (x_1||...||x_N||t), where x_i, t are SEL_TREEs + SYNOPSIS + or_sel_tree() + param Context info for the operation + tree SEL_TREE to add to this imerge + + DESCRIPTION + The function just adds the range tree 'tree' to the range trees + of this imerge. RETURN - 0 - OK - -1 - Out of memory. + 0 if the operation is success + -1 if the function runs out memory */ int SEL_IMERGE::or_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree) @@ -809,96 +935,294 @@ int SEL_IMERGE::or_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree) /* - Perform OR operation on this SEL_IMERGE and supplied SEL_TREE new_tree, - combining new_tree with one of the trees in this SEL_IMERGE if they both - have SEL_ARGs for the same key. + Check if any of the range trees of this imerge intersects with a given tree + + SYNOPSIS + have_common_keys() + param Context info for the function + tree SEL_TREE intersection with the imerge range trees is checked for + + DESCRIPTION + The function checks whether there is any range tree rt_i in this imerge + such that there are some indexes for which ranges are defined in both + rt_i and the range part of the SEL_TREE tree. + To check this the function calls the function sel_trees_have_common_keys. + + RETURN + TRUE if there are such range trees in this imerge + FALSE otherwise +*/ + +bool SEL_IMERGE::have_common_keys(RANGE_OPT_PARAM *param, SEL_TREE *tree) +{ + for (SEL_TREE** or_tree= trees, **bound= trees_next; + or_tree != bound; or_tree++) + { + key_map common_keys; + if (sel_trees_have_common_keys(param, *or_tree, tree, &common_keys)) + return TRUE; + } + return FALSE; +} + + +/* + Perform AND operation for this imerge and the range part of a tree + + SYNOPSIS + and_sel_tree() + param Context info for the operation + tree SEL_TREE for the second operand of the operation + new_imerge OUT imerge for the result of the operation + + DESCRIPTION + This function performs AND operation for this imerge m and the + range part of the SEL_TREE tree rt. In other words the function + pushes rt into this imerge. The resulting imerge is returned in + the parameter new_imerge. + If this imerge m represent the formula + RT_1 OR ... OR RT_k + then the resulting imerge of the function represents the formula + (RT_1 AND RT) OR ... (RT_k AND RT) + The function calls the function and_range_trees to construct the + range tree representing (RT_i AND RT). + + NOTE + The function may return an empty imerge without any range trees + + RETURN + 0 if the operation is a success + -1 otherwise: there is not enough memory to perform the operation +*/ + +int SEL_IMERGE::and_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree, + SEL_IMERGE *new_imerge) +{ + for (SEL_TREE** or_tree= trees; or_tree != trees_next; or_tree++) + { + SEL_TREE *result= 0; + key_map result_keys; + if (!(result= new SEL_TREE())) + return (-1); + if (!and_range_trees(param, *or_tree, tree, result)) + { + if (new_imerge->or_sel_tree(param, result)) + return (-1); + } + } + return 0; +} + + +/* + Perform OR operation on this imerge and the range part of a tree SYNOPSIS or_sel_tree_with_checks() - param PARAM from SQL_SELECT::test_quick_select - new_tree SEL_TREE with type KEY or KEY_SMALLER. + param Context info for the operation + tree SEL_TREE whose range part is to be ored + is_first_check_pass <=> the first call of the function for this imerge + is_last_check_pass OUT <=> no more calls of the function for this imerge - NOTES - This does the following: - (t_1||...||t_k)||new_tree = - either - = (t_1||...||t_k||new_tree) - or - = (t_1||....||(t_j|| new_tree)||...||t_k), + DESCRIPTION + The functions performs OR operation on this imerge m and the range part + of the SEL_TREE tree rt. It always replaces this imerge with the result + of the operation. + + The operation can be performed in two different modes: with + is_first_check_pass==TRUE and is_first_check_pass==FALSE, transforming + this imerge differently. - where t_i, y are SEL_TREEs. - new_tree is combined with the first t_j it has a SEL_ARG on common - key with. As a consequence of this, choice of keys to do index_merge - read may depend on the order of conditions in WHERE part of the query. + Given this imerge represents the formula + RT_1 OR ... OR RT_k: + 1. In the first mode, when is_first_check_pass==TRUE : + 1.1. If rt must be ored(see the function sel_trees_must_be_ored) with + some rt_j (there may be only one such range tree in the imerge) + then the function produces the imerge representing the formula + RT_1 OR ... OR (RT_j OR RT) OR ... OR RT_k, + where the tree for (RT_j OR RT) is built by oring the pairs + of SEL_ARG trees for the corresponding indexes + 1.2. Otherwise the function produces the imerge representing the formula: + RT_1 OR ... OR RT_k OR RT. + + 2. In the second mode, when is_first_check_pass==FALSE : + 2.1. For each rt_j in the imerge that can be ored (see the function + sel_trees_can_be_ored), but not must be ored, with rt the function + replaces rt_j for a range tree such that for each index for which + ranges are defined in both in rt_j and rt the tree contains the + result of oring of these ranges. + 2.2. In other cases the function does not produce any imerge. + + When is_first_check==TRUE the function returns FALSE in the parameter + is_last_check_pass if there is no rt_j such that rt_j can be ored with rt, + but, at the same time, it's not true that rt_j must be ored with rt. + When is_first_check==FALSE the function always returns FALSE in the + parameter is_last_check_pass. + RETURN - 0 OK - 1 One of the trees was combined with new_tree to SEL_TREE::ALWAYS, - and (*this) should be discarded. - -1 An error occurred. + 1 The result of oring of rt_j and rt that must be ored returns the + the range tree with type==SEL_TREE::ALWAYS + (in this case the imerge m should be discarded) + -1 The function runs out of memory + 0 in all other cases */ -int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param, SEL_TREE *new_tree) +int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param, + SEL_TREE *tree, + bool is_first_check_pass, + bool *is_last_check_pass) { - for (SEL_TREE** tree = trees; - tree != trees_next; - tree++) + *is_last_check_pass= TRUE; + for (SEL_TREE** or_tree = trees; + or_tree != trees_next; + or_tree++) { - if (sel_trees_can_be_ored(*tree, new_tree, param)) + SEL_TREE *result= 0; + key_map result_keys; + key_map ored_keys; + if (sel_trees_can_be_ored(param, *or_tree, tree, &ored_keys)) { - *tree = tree_or(param, *tree, new_tree); - if (!*tree) - return 1; - if (((*tree)->type == SEL_TREE::MAYBE) || - ((*tree)->type == SEL_TREE::ALWAYS)) + bool must_be_ored= sel_trees_must_be_ored(param, *or_tree, tree, + ored_keys); + if (must_be_ored == is_first_check_pass) { + result_keys.clear_all(); + result= *or_tree; + for (uint key_no= 0; key_no < param->keys; key_no++) + { + if (!ored_keys.is_set(key_no)) + { + result->keys[key_no]= 0; + continue; + } + SEL_ARG *key1= (*or_tree)->keys[key_no]; + SEL_ARG *key2= tree->keys[key_no]; + key2->incr_refs(); + if ((result->keys[key_no]= key_or(param, key1, key2))) + { + + result_keys.set_bit(key_no); +#ifdef EXTRA_DEBUG + if (param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS) + { + key1= result->keys[key_no]; + (key1)->test_use_count(key1); + } +#endif + } + } + } + else if(is_first_check_pass) + *is_last_check_pass= FALSE; + } + + if (result) + { + if (result_keys.is_clear_all()) + result->type= SEL_TREE::ALWAYS; + *is_last_check_pass= TRUE; + if ((result->type == SEL_TREE::MAYBE) || + (result->type == SEL_TREE::ALWAYS)) return 1; /* SEL_TREE::IMPOSSIBLE is impossible here */ - return 0; + result->keys_map= result_keys; + *or_tree= result; + if (is_first_check_pass) + return 0; } } + if (!is_first_check_pass) + return 0; - /* New tree cannot be combined with any of existing trees. */ - return or_sel_tree(param, new_tree); + if (!*is_last_check_pass && + !(tree= new SEL_TREE(tree, FALSE, param))) + return (-1); + return or_sel_tree(param, tree); } /* - Perform OR operation on this index_merge and supplied index_merge list. + Perform OR operation on this imerge and and another imerge + SYNOPSIS + or_sel_tree_with_checks() + param Context info for the operation + imerge The second operand of the operation + is_first_check_pass <=> the first call of the function for this imerge + is_last_check_pass OUT <=> no more calls of the function for this imerge + + DESCRIPTION + For each range tree rt from 'imerge' the function calls the method + SEL_IMERGE::or_sel_tree_with_checks that performs OR operation on this + SEL_IMERGE object m and the tree rt. The mode of the operation is + specified by the parameter is_first_check_pass. Each call of + SEL_IMERGE::or_sel_tree_with_checks transforms this SEL_IMERGE object m. + The function returns FALSE in the prameter is_last_check_pass if + at least one of the calls of SEL_IMERGE::or_sel_tree_with_checks + returns FALSE as the value of its last parameter. + RETURN - 0 - OK - 1 - One of conditions in result is always TRUE and this SEL_IMERGE - should be discarded. - -1 - An error occurred + 1 One of the calls of SEL_IMERGE::or_sel_tree_with_checks returns 1. + (in this case the imerge m should be discarded) + -1 The function runs out of memory + 0 in all other cases */ -int SEL_IMERGE::or_sel_imerge_with_checks(RANGE_OPT_PARAM *param, SEL_IMERGE* imerge) +int SEL_IMERGE::or_sel_imerge_with_checks(RANGE_OPT_PARAM *param, + SEL_IMERGE* imerge, + bool is_first_check_pass, + bool *is_last_check_pass) { + *is_last_check_pass= TRUE; for (SEL_TREE** tree= imerge->trees; tree != imerge->trees_next; tree++) { - if (or_sel_tree_with_checks(param, *tree)) - return 1; + uint rc; + bool is_last; + rc= or_sel_tree_with_checks(param, *tree, is_first_check_pass, &is_last); + if (!is_last) + *is_last_check_pass= FALSE; + if (rc) + return rc; } return 0; } -SEL_TREE::SEL_TREE(SEL_TREE *arg, RANGE_OPT_PARAM *param): Sql_alloc() +/* + Copy constructor for SEL_TREE objects + + SYNOPSIS + SEL_TREE + arg The source tree for the constructor + without_merges <=> only the range part of the tree arg is copied + param Context info for the operation + + DESCRIPTION + The constructor creates a full copy of the SEL_TREE arg if + the prameter without_merges==FALSE. Otherwise a tree is created + that contains the copy only of the range part of the tree arg. +*/ + +SEL_TREE::SEL_TREE(SEL_TREE *arg, bool without_merges, + RANGE_OPT_PARAM *param): Sql_alloc() { keys_map= arg->keys_map; type= arg->type; - for (int idx= 0; idx < MAX_KEY; idx++) + for (uint idx= 0; idx < param->keys; idx++) { if ((keys[idx]= arg->keys[idx])) - keys[idx]->increment_use_count(1); + keys[idx]->incr_refs(); } + if (without_merges) + return; + List_iterator it(arg->merges); for (SEL_IMERGE *el= it++; el; el= it++) { - SEL_IMERGE *merge= new SEL_IMERGE(el, param); + SEL_IMERGE *merge= new SEL_IMERGE(el, 0, param); if (!merge || merge->trees == merge->trees_next) { merges.empty(); @@ -909,7 +1233,23 @@ SEL_TREE::SEL_TREE(SEL_TREE *arg, RANGE_OPT_PARAM *param): Sql_alloc() } -SEL_IMERGE::SEL_IMERGE (SEL_IMERGE *arg, RANGE_OPT_PARAM *param) : Sql_alloc() +/* + Copy constructor for SEL_IMERGE objects + + SYNOPSIS + SEL_IMERGE + arg The source imerge for the constructor + cnt How many trees from arg are to be copied + param Context info for the operation + + DESCRIPTION + The cnt==0 then the constructor creates a full copy of the + imerge arg. Otherwise only the first cnt trees of the imerge + are copied. +*/ + +SEL_IMERGE::SEL_IMERGE(SEL_IMERGE *arg, uint cnt, + RANGE_OPT_PARAM *param) : Sql_alloc() { uint elements= (arg->trees_end - arg->trees); if (elements > PREALLOCED_TREES) @@ -921,13 +1261,13 @@ SEL_IMERGE::SEL_IMERGE (SEL_IMERGE *arg, RANGE_OPT_PARAM *param) : Sql_alloc() else trees= &trees_prealloced[0]; - trees_next= trees; + trees_next= trees + (cnt ? cnt : arg->trees_next-arg->trees); trees_end= trees + elements; - for (SEL_TREE **tree = trees, **arg_tree= arg->trees; tree < trees_end; + for (SEL_TREE **tree = trees, **arg_tree= arg->trees; tree < trees_next; tree++, arg_tree++) { - if (!(*tree= new SEL_TREE(*arg_tree, param))) + if (!(*tree= new SEL_TREE(*arg_tree, FALSE, param))) goto mem_err; } @@ -941,7 +1281,19 @@ mem_err: /* - Perform AND operation on two index_merge lists and store result in *im1. + Perform AND operation on two imerge lists + + SYNOPSIS + imerge_list_and_list() + param Context info for the operation + im1 The first imerge list for the operation + im2 The second imerge list for the operation + + DESCRIPTION + The function just appends the imerge list im2 to the imerge list im1 + + RETURN VALUE + none */ inline void imerge_list_and_list(List *im1, List *im2) @@ -951,73 +1303,242 @@ inline void imerge_list_and_list(List *im1, List *im2) /* - Perform OR operation on 2 index_merge lists, storing result in first list. + Perform OR operation on two imerge lists - NOTES - The following conversion is implemented: - (a_1 &&...&& a_N)||(b_1 &&...&& b_K) = AND_i,j(a_i || b_j) => - => (a_1||b_1). + SYNOPSIS + imerge_list_or_list() + param Context info for the operation + im1 The first imerge list for the operation + im2 The second imerge list for the operation + + DESCRIPTION + Assuming that the first imerge list represents the formula + F1= M1_1 AND ... AND M1_k1 + while the second imerge list represents the formula + F2= M2_1 AND ... AND M2_k2, + where M1_i= RT1_i_1 OR ... OR RT1_i_l1i (i in [1..k1]) + and M2_i = RT2_i_1 OR ... OR RT2_i_l2i (i in [1..k2]), + the function builds a list of imerges for some formula that can be + inferred from the formula (F1 OR F2). - i.e. all conjuncts except the first one are currently dropped. - This is done to avoid producing N*K ways to do index_merge. + More exactly the function builds imerges for the formula (M1_1 OR M2_1). + Note that + (F1 OR F2) = (M1_1 AND ... AND M1_k1) OR (M2_1 AND ... AND M2_k2) = + AND (M1_i OR M2_j) (i in [1..k1], j in [1..k2]) => + M1_1 OR M2_1. + So (M1_1 OR M2_1) is indeed an inference formula for (F1 OR F2). - If (a_1||b_1) produce a condition that is always TRUE, NULL is returned - and index_merge is discarded (while it is actually possible to try - harder). - - As a consequence of this, choice of keys to do index_merge read may depend - on the order of conditions in WHERE part of the query. + To build imerges for the formula (M1_1 OR M2_1) the function invokes, + possibly twice, the method SEL_IMERGE::or_sel_imerge_with_checks + for the imerge m1_1. + At its first invocation the method SEL_IMERGE::or_sel_imerge_with_checks + performs OR operation on the imerge m1_1 and the range tree rt2_1_1 by + calling SEL_IMERGE::or_sel_tree_with_checks with is_first_pass_check==TRUE. + The resulting imerge of the operation is ored with the next range tree of + the imerge m2_1. This oring continues until the last range tree from + m2_1 has been ored. + At its second invocation the method SEL_IMERGE::or_sel_imerge_with_checks + performs the same sequence of OR operations, but now calling + SEL_IMERGE::or_sel_tree_with_checks with is_first_pass_check==FALSE. + The imerges that the operation produces replace those in the list im1 + RETURN - 0 OK, result is stored in *im1 - other Error, both passed lists are unusable + 0 if the operation is a success + -1 if the function has run out of memory */ int imerge_list_or_list(RANGE_OPT_PARAM *param, List *im1, List *im2) { + + uint rc; + bool is_last_check_pass= FALSE; + SEL_IMERGE *imerge= im1->head(); + uint elems= imerge->trees_next-imerge->trees; im1->empty(); im1->push_back(imerge); - return imerge->or_sel_imerge_with_checks(param, im2->head()); + rc= imerge->or_sel_imerge_with_checks(param, im2->head(), + TRUE, &is_last_check_pass); + if (rc) + { + if (rc == 1) + { + im1->empty(); + rc= 0; + } + return rc; + } + + if (!is_last_check_pass) + { + SEL_IMERGE* new_imerge= new SEL_IMERGE(imerge, elems, param); + if (new_imerge) + { + is_last_check_pass= TRUE; + rc= new_imerge->or_sel_imerge_with_checks(param, im2->head(), + FALSE, &is_last_check_pass); + if (!rc) + im1->push_back(new_imerge); + } + } + return rc; } /* - Perform OR operation on index_merge list and key tree. + Perform OR operation for each imerge from a list and the range part of a tree + SYNOPSIS + imerge_list_or_tree() + param Context info for the operation + merges The list of imerges to be ored with the range part of tree + tree SEL_TREE whose range part is to be ored with the imerges + + DESCRIPTION + For each imerge mi from the list 'merges' the function performes OR + operation with mi and the range part of 'tree' rt, producing one or + two imerges. + + Given the merge mi represent the formula RTi_1 OR ... OR RTi_k, + the function forms the merges by the following rules: + + 1. If rt cannot be ored with any of the trees rti the function just + produces an imerge that represents the formula + RTi_1 OR ... RTi_k OR RT. + 2. If there exist a tree rtj that must be ored with rt the function + produces an imerge the represents the formula + RTi_1 OR ... OR (RTi_j OR RT) OR ... OR RTi_k, + where the range tree for (RTi_j OR RT) is constructed by oring the + SEL_ARG trees that must be ored. + 3. For each rti_j that can be ored with rt the function produces + the new tree rti_j' and substitutes rti_j for this new range tree. + + In any case the function removes mi from the list and then adds all + produced imerges. + + To build imerges by rules 1-3 the function calls the method + SEL_IMERGE::or_sel_tree_with_checks, possibly twice. With the first + call it passes TRUE for the third parameter of the function. + At this first call imerges by rules 1-2 are built. If the call + returns FALSE as the return value of its fourth parameter then the + function are called for the second time. At this call the imerge + of rule 3 is produced. + + If a call of SEL_IMERGE::or_sel_tree_with_checks returns 1 then + then it means that the produced tree contains an always true + range tree and the whole imerge can be discarded. + RETURN - 0 OK, result is stored in *im1. - other Error + 1 if no imerges are produced + 0 otherwise */ +static int imerge_list_or_tree(RANGE_OPT_PARAM *param, - List *im1, + List *merges, SEL_TREE *tree) { + SEL_IMERGE *imerge; - List_iterator it(*im1); - bool tree_used= FALSE; + List additional_merges; + List_iterator it(*merges); + while ((imerge= it++)) { - SEL_TREE *or_tree; - if (tree_used) + bool is_last_check_pass; + int rc= 0; + int rc1= 0; + SEL_TREE *or_tree= new SEL_TREE (tree, FALSE, param); + if (or_tree) { - or_tree= new SEL_TREE (tree, param); - if (!or_tree || - (or_tree->keys_map.is_clear_all() && or_tree->merges.is_empty())) - return FALSE; + uint elems= imerge->trees_next-imerge->trees; + rc= imerge->or_sel_tree_with_checks(param, or_tree, + TRUE, &is_last_check_pass); + if (!is_last_check_pass) + { + SEL_IMERGE *new_imerge= new SEL_IMERGE(imerge, elems, param); + if (new_imerge) + { + rc1= new_imerge->or_sel_tree_with_checks(param, or_tree, + FALSE, &is_last_check_pass); + if (!rc1) + additional_merges.push_back(new_imerge); + } + } } - else - or_tree= tree; - - if (imerge->or_sel_tree_with_checks(param, or_tree)) + if (rc || rc1 || !or_tree) it.remove(); - tree_used= TRUE; } - return im1->is_empty(); + + merges->concat(&additional_merges); + return merges->is_empty(); +} + + +/* + Perform pushdown operation of the range part of a tree into given imerges + + SYNOPSIS + imerge_list_and_tree() + param Context info for the operation + merges IN/OUT List of imerges to push the range part of 'tree' into + tree SEL_TREE whose range part is to be pushed into imerges + + DESCRIPTION + For each imerge from the list merges the function pushes the range part + rt of 'tree' into the imerge. + More exactly if the imerge mi from the list represents the formula + RTi_1 OR ... OR RTi_k + the function bulds a new imerge that represents the formula + (RTi_1 AND RT) OR ... OR (RTi_k AND RT) + and adds this imerge to the list merges. + To perform this pushdown operation the function calls the method + SEL_IMERGE::and_sel_tree. + For any imerge mi the new imerge is not created if for each pair of + trees rti_j and rt the intersection of the indexes with defined ranges + is empty. + If the result of the pushdown operation for the imerge mi returns an + imerge with no trees then then not only nothing is added to the list + merges but mi itself is removed from the list. + + RETURN + 1 if no imerges are left in the list merges + 0 otherwise +*/ + +static +int imerge_list_and_tree(RANGE_OPT_PARAM *param, + List *merges, + SEL_TREE *tree) +{ + SEL_IMERGE *imerge; + SEL_IMERGE *new_imerge= NULL; + List new_merges; + List_iterator it(*merges); + + while ((imerge= it++)) + { + if (!new_imerge) + new_imerge= new SEL_IMERGE(); + if (imerge->have_common_keys(param, tree) && + new_imerge && !imerge->and_sel_tree(param, tree, new_imerge)) + { + if (new_imerge->trees == new_imerge->trees_next) + it.remove(); + else + { + new_merges.push_back(new_imerge); + new_imerge= NULL; + } + } + } + imerge_list_and_list(&new_merges, merges); + *merges= new_merges; + return merges->is_empty(); } @@ -2367,72 +2888,73 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, It is possible to use a range-based quick select (but it might be slower than 'all' table scan). */ - if (tree->merges.is_empty()) + TRP_RANGE *range_trp; + TRP_ROR_INTERSECT *rori_trp; + bool can_build_covering= FALSE; + + remove_nonrange_trees(¶m, tree); + + /* Get best 'range' plan and prepare data for making other plans */ + if ((range_trp= get_key_scans_params(¶m, tree, FALSE, TRUE, + best_read_time))) { - TRP_RANGE *range_trp; - TRP_ROR_INTERSECT *rori_trp; - bool can_build_covering= FALSE; - - /* Get best 'range' plan and prepare data for making other plans */ - if ((range_trp= get_key_scans_params(¶m, tree, FALSE, TRUE, - best_read_time))) - { - best_trp= range_trp; - best_read_time= best_trp->read_cost; - } + best_trp= range_trp; + best_read_time= best_trp->read_cost; + } + /* + Simultaneous key scans and row deletes on several handler + objects are not allowed so don't use ROR-intersection for + table deletes. + */ + if ((thd->lex->sql_command != SQLCOM_DELETE) && + optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE)) + { /* - Simultaneous key scans and row deletes on several handler - objects are not allowed so don't use ROR-intersection for - table deletes. + Get best non-covering ROR-intersection plan and prepare data for + building covering ROR-intersection. */ - if ((thd->lex->sql_command != SQLCOM_DELETE) && - optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE)) + if ((rori_trp= get_best_ror_intersect(¶m, tree, best_read_time, + &can_build_covering))) { + best_trp= rori_trp; + best_read_time= best_trp->read_cost; /* - Get best non-covering ROR-intersection plan and prepare data for - building covering ROR-intersection. + Try constructing covering ROR-intersect only if it looks possible + and worth doing. */ - if ((rori_trp= get_best_ror_intersect(¶m, tree, best_read_time, - &can_build_covering))) - { + if (!rori_trp->is_covering && can_build_covering && + (rori_trp= get_best_covering_ror_intersect(¶m, tree, + best_read_time))) best_trp= rori_trp; - best_read_time= best_trp->read_cost; - /* - Try constructing covering ROR-intersect only if it looks possible - and worth doing. - */ - if (!rori_trp->is_covering && can_build_covering && - (rori_trp= get_best_covering_ror_intersect(¶m, tree, - best_read_time))) - best_trp= rori_trp; - } } } - else + + if (optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE)) { - if (optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE)) + /* Try creating index_merge/ROR-union scan. */ + SEL_IMERGE *imerge; + TABLE_READ_PLAN *best_conj_trp= NULL, *new_conj_trp; + LINT_INIT(new_conj_trp); /* no empty index_merge lists possible */ + DBUG_PRINT("info",("No range reads possible," + " trying to construct index_merge")); + List_iterator_fast it(tree->merges); + while ((imerge= it++)) { - /* Try creating index_merge/ROR-union scan. */ - SEL_IMERGE *imerge; - TABLE_READ_PLAN *best_conj_trp= NULL, *new_conj_trp; - LINT_INIT(new_conj_trp); /* no empty index_merge lists possible */ - DBUG_PRINT("info",("No range reads possible," - " trying to construct index_merge")); - List_iterator_fast it(tree->merges); - while ((imerge= it++)) + new_conj_trp= get_best_disjunct_quick(¶m, imerge, best_read_time); + if (new_conj_trp) + set_if_smaller(param.table->quick_condition_rows, + new_conj_trp->records); + if (new_conj_trp && + (!best_conj_trp || + new_conj_trp->read_cost < best_conj_trp->read_cost)) { - new_conj_trp= get_best_disjunct_quick(¶m, imerge, best_read_time); - if (new_conj_trp) - set_if_smaller(param.table->quick_condition_rows, - new_conj_trp->records); - if (!best_conj_trp || (new_conj_trp && new_conj_trp->read_cost < - best_conj_trp->read_cost)) - best_conj_trp= new_conj_trp; + best_conj_trp= new_conj_trp; + best_read_time= best_conj_trp->read_cost; } - if (best_conj_trp) - best_trp= best_conj_trp; } + if (best_conj_trp) + best_trp= best_conj_trp; } } @@ -3696,7 +4218,6 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, { SEL_TREE **ptree; TRP_INDEX_MERGE *imerge_trp= NULL; - uint n_child_scans= imerge->trees_next - imerge->trees; TRP_RANGE **range_scans; TRP_RANGE **cur_child; TRP_RANGE **cpk_scan= NULL; @@ -3716,6 +4237,26 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, DBUG_ENTER("get_best_disjunct_quick"); DBUG_PRINT("info", ("Full table scan cost: %g", read_time)); + /* + In every tree of imerge remove SEL_ARG trees that do not make ranges. + Remove a tree from imerge if no SEL_ARG trees remain in it. + */ + SEL_TREE **new_trees_next= imerge->trees; + for (ptree= new_trees_next; ptree != imerge->trees_next; ptree++) + { + if (remove_nonrange_trees(param, *ptree)) + continue; + if (ptree > new_trees_next) + *new_trees_next= *ptree; + new_trees_next++; + } + imerge->trees_next= new_trees_next; + + uint n_child_scans= imerge->trees_next - imerge->trees; + + if (!n_child_scans) + DBUG_RETURN(NULL); + if (!(range_scans= (TRP_RANGE**)alloc_root(param->mem_root, sizeof(TRP_RANGE*)* n_child_scans))) @@ -3835,6 +4376,13 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, imerge_trp->range_scans_end= range_scans + n_child_scans; read_time= imerge_cost; } + if (imerge_trp) + { + TABLE_READ_PLAN *trp= merge_same_index_scans(param, imerge, imerge_trp, + read_time); + if (trp != imerge_trp) + DBUG_RETURN(trp); + } } build_ror_index_merge: @@ -3850,6 +4398,7 @@ build_ror_index_merge: sizeof(TABLE_READ_PLAN*)* n_child_scans))) DBUG_RETURN(imerge_trp); + skip_to_ror_scan: roru_index_costs= 0.0; roru_total_records= 0; @@ -3933,7 +4482,116 @@ skip_to_ror_scan: DBUG_RETURN(roru); } } - DBUG_RETURN(imerge_trp); + DBUG_RETURN(imerge_trp); +} + + +/* + Merge index scans for the same indexes in an index merge plan + + SYNOPSIS + merge_same_index_scans() + param Context info for the operation + imerge IN/OUT SEL_IMERGE from which imerge_trp has been extracted + imerge_trp The index merge plan where index scans for the same + indexes are to be merges + read_time The upper bound for the cost of the plan to be evaluated + + DESRIPTION + For the given index merge plan imerge_trp extracted from the SEL_MERGE + imerge the function looks for range scans with the same indexes and merges + them into SEL_ARG trees. Then for each such SEL_ARG tree r_i the function + creates a range tree rt_i that contains only r_i. All rt_i are joined + into one index merge that replaces the original index merge imerge. + The function calls get_best_disjunct_quick for the new index merge to + get a new index merge plan that contains index scans only for different + indexes. + If there are no index scans for the same index in the original index + merge plan the function does not change the original imerge and returns + imerge_trp as its result. + + RETURN + The original or or improved index merge plan +*/ + +static +TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge, + TRP_INDEX_MERGE *imerge_trp, + double read_time) +{ + uint16 first_scan_tree_idx[MAX_KEY]; + SEL_TREE **tree; + TRP_RANGE **cur_child; + uint removed_cnt= 0; + + DBUG_ENTER("merge_same_index_scans"); + + bzero(first_scan_tree_idx, sizeof(first_scan_tree_idx[0])*param->keys); + + for (tree= imerge->trees, cur_child= imerge_trp->range_scans; + tree != imerge->trees_next; + tree++, cur_child++) + { + DBUG_ASSERT(tree); + uint key_idx= (*cur_child)->key_idx; + uint16 *tree_idx_ptr= &first_scan_tree_idx[key_idx]; + if (!*tree_idx_ptr) + *tree_idx_ptr= (uint16) (tree-imerge->trees+1); + else + { + SEL_TREE **changed_tree= imerge->trees+(*tree_idx_ptr-1); + SEL_ARG *key= (*changed_tree)->keys[key_idx]; + bzero((*changed_tree)->keys, + sizeof((*changed_tree)->keys[0])*param->keys); + (*changed_tree)->keys_map.clear_all(); + if (((*changed_tree)->keys[key_idx]= + key_or(param, key, (*tree)->keys[key_idx]))) + (*changed_tree)->keys_map.set_bit(key_idx); + *tree= NULL; + removed_cnt++; + } + } + if (!removed_cnt) + DBUG_RETURN(imerge_trp); + + TABLE_READ_PLAN *trp= NULL; + SEL_TREE **new_trees_next= imerge->trees; + for (tree= new_trees_next; tree != imerge->trees_next; tree++) + { + if (!*tree) + continue; + if (tree > new_trees_next) + *new_trees_next= *tree; + new_trees_next++; + } + imerge->trees_next= new_trees_next; + + DBUG_ASSERT(imerge->trees_next>imerge->trees); + + if (imerge->trees_next-imerge->trees > 1) + trp= get_best_disjunct_quick(param, imerge, read_time); + else + { + /* + This alternative theoretically can be reached when the cost + of the index merge for such a formula as + (key1 BETWEEN c1_1 AND c1_2) AND key2 > c2 OR + (key1 BETWEEN c1_3 AND c1_4) AND key3 > c3 + is estimated as being cheaper than the cost of index scan for + the formula + (key1 BETWEEN c1_1 AND c1_2) OR (key1 BETWEEN c1_3 AND c1_4) + + In the current code this may happen for two reasons: + 1. for a single index range scan data records are accessed in + a random order + 2. the functions that estimate the cost of a range scan and an + index merge retrievals are not well calibrated + */ + trp= get_key_scans_params(param, *imerge->trees, FALSE, TRUE, + read_time); + } + + DBUG_RETURN(trp); } @@ -4029,7 +4687,7 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg) ror_scan->key_rec_length= (param->table->key_info[keynr].key_length + param->table->file->ref_length); ror_scan->sel_arg= sel_arg; - ror_scan->records= param->table->quick_rows[keynr]; + ror_scan->records= param->quick_rows[keynr]; if (!(bitmap_buf= (my_bitmap_map*) alloc_root(param->mem_root, param->fields_bitmap_size))) @@ -4049,7 +4707,7 @@ ROR_SCAN_INFO *make_ror_scan(const PARAM *param, int idx, SEL_ARG *sel_arg) bitmap_set_bit(&ror_scan->covered_fields, key_part->fieldnr-1); } ror_scan->index_read_cost= - get_index_only_read_time(param, param->table->quick_rows[ror_scan->keynr], + get_index_only_read_time(param, param->quick_rows[ror_scan->keynr], ror_scan->keynr); DBUG_RETURN(ror_scan); } @@ -4335,7 +4993,7 @@ static double ror_scan_selectivity(const ROR_INTERSECT_INFO *info, } if (!prev_covered) { - double tmp= rows2double(info->param->table->quick_rows[scan->keynr]) / + double tmp= rows2double(info->param->quick_rows[scan->keynr]) / rows2double(prev_records); DBUG_PRINT("info", ("Selectivity multiplier: %g", tmp)); selectivity_mult *= tmp; @@ -4414,7 +5072,7 @@ static bool ror_intersect_add(ROR_INTERSECT_INFO *info, } else { - info->index_records += info->param->table->quick_rows[ror_scan->keynr]; + info->index_records += info->param->quick_rows[ror_scan->keynr]; info->index_scan_costs += ror_scan->index_read_cost; bitmap_union(&info->covered_fields, &ror_scan->covered_fields); if (!info->is_covering && bitmap_is_subset(&info->param->needed_fields, @@ -6044,13 +6702,138 @@ sel_add(SEL_ARG *key1,SEL_ARG *key2) return root; } -#define CLONE_KEY1_MAYBE 1 -#define CLONE_KEY2_MAYBE 2 -#define swap_clone_flag(A) ((A & 1) << 1) | ((A & 2) >> 1) +/* + Build a range tree for the conjunction of the range parts of two trees -static SEL_TREE * -tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2) + SYNOPSIS + and_range_trees() + param Context info for the operation + tree1 SEL_TREE for the first conjunct + tree2 SEL_TREE for the second conjunct + result SEL_TREE for the result + + DESCRIPTION + This function takes range parts of two trees tree1 and tree2 and builds + a range tree for the conjunction of the formulas that these two range parts + represent. + More exactly: + if the range part of tree1 represents the normalized formula + R1_1 AND ... AND R1_k, + and the range part of tree2 represents the normalized formula + R2_1 AND ... AND R2_k, + then the range part of the result represents the formula: + RT = R_1 AND ... AND R_k, where R_i=(R1_i AND R2_i) for each i from [1..k] + + The function assumes that tree1 is never equal to tree2. At the same + time the tree result can be the same as tree1 (but never as tree2). + If result==tree1 then rt replaces the range part of tree1 leaving + imerges as they are. + if result!=tree1 than it is assumed that the SEL_ARG trees in tree1 and + tree2 should be preserved. Otherwise they can be destroyed. + + RETURN + 1 if the type the result tree is SEL_TREE::IMPOSSIBLE + 0 otherwise +*/ + +static +int and_range_trees(RANGE_OPT_PARAM *param, SEL_TREE *tree1, SEL_TREE *tree2, + SEL_TREE *result) +{ + DBUG_ENTER("and_ranges"); + key_map result_keys; + result_keys.clear_all(); + key_map anded_keys= tree1->keys_map; + anded_keys.merge(tree2->keys_map); + int key_no; + key_map::Iterator it(anded_keys); + while ((key_no= it++) != key_map::Iterator::BITMAP_END) + { + uint flag=0; + SEL_ARG *key1= tree1->keys[key_no]; + SEL_ARG *key2= tree2->keys[key_no]; + if (key1 && !key1->simple_key()) + flag|= CLONE_KEY1_MAYBE; + if (key2 && !key2->simple_key()) + flag|=CLONE_KEY2_MAYBE; + if (result != tree1) + { + if (key1) + key1->incr_refs(); + if (key2) + key2->incr_refs(); + } + SEL_ARG *key; + if ((result->keys[key_no]= key =key_and(param, key1, key2, flag))) + { + if (key && key->type == SEL_ARG::IMPOSSIBLE) + { + result->type= SEL_TREE::IMPOSSIBLE; + DBUG_RETURN(1); + } + result_keys.set_bit(key_no); +#ifdef EXTRA_DEBUG + if (param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS) + key->test_use_count(key); +#endif + } + } + result->keys_map= result_keys; + DBUG_RETURN(0); +} + + +/* + Build a SEL_TREE for a conjunction out of such trees for the conjuncts + + SYNOPSIS + tree_and() + param Context info for the operation + tree1 SEL_TREE for the first conjunct + tree2 SEL_TREE for the second conjunct + + DESCRIPTION + This function builds a tree for the formula (A AND B) out of the trees + tree1 and tree2 that has been built for the formulas A and B respectively. + + In a general case + tree1 represents the formula RT1 AND MT1, + where RT1 = R1_1 AND ... AND R1_k1, MT1=M1_1 AND ... AND M1_l1; + tree2 represents the formula RT2 AND MT2 + where RT2 = R2_1 AND ... AND R2_k2, MT2=M2_1 and ... and M2_l2. + + The result tree will represent the formula of the the following structure: + RT AND MT1 AND MT2 AND RT1MT2 AND RT2MT1, such that + rt is a tree obtained by range intersection of trees tree1 and tree2, + RT1MT2 = RT1M2_1 AND ... AND RT1M2_l2, + RT2MT1 = RT2M1_1 AND ... AND RT2M1_l1, + where rt1m2_i (i=1,...,l2) is the result of the pushdown operation + of range tree rt1 into imerge m2_i, while rt2m1_j (j=1,...,l1) is the + result of the pushdown operation of range tree rt2 into imerge m1_j. + + RT1MT2/RT2MT is empty if MT2/MT1 is empty. + + The range intersection of two range trees is produced by the function + and_range_trees. The pushdown of a range tree to a imerge is performed + by the function imerge_list_and_tree. This function may produce imerges + containing only one range tree. Such trees are intersected with rt and + the result of intersection is returned as the range part of the result + tree, while the corresponding imerges are removed altogether from its + imerge part. + + NOTE. + The pushdown operation of range trees into imerges is needed to be able + to construct valid imerges for the condition like this: + key1_p1=c1 AND (key1_p2 BETWEEN c21 AND c22 OR key2 < c2) + + RETURN + The result tree, if a success + 0 - otherwise. +*/ + +static +SEL_TREE *tree_and(RANGE_OPT_PARAM *param, SEL_TREE *tree1, SEL_TREE *tree2) { DBUG_ENTER("tree_and"); if (!tree1) @@ -6072,87 +6855,208 @@ tree_and(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2) tree1->type=SEL_TREE::KEY_SMALLER; DBUG_RETURN(tree1); } - key_map result_keys; - result_keys.clear_all(); - - /* Join the trees key per key */ - SEL_ARG **key1,**key2,**end; - for (key1= tree1->keys,key2= tree2->keys,end=key1+param->keys ; - key1 != end ; key1++,key2++) - { - uint flag=0; - if (*key1 || *key2) - { - if (*key1 && !(*key1)->simple_key()) - flag|=CLONE_KEY1_MAYBE; - if (*key2 && !(*key2)->simple_key()) - flag|=CLONE_KEY2_MAYBE; - *key1=key_and(param, *key1, *key2, flag); - if (*key1 && (*key1)->type == SEL_ARG::IMPOSSIBLE) - { - tree1->type= SEL_TREE::IMPOSSIBLE; - DBUG_RETURN(tree1); - } - result_keys.set_bit(key1 - tree1->keys); -#ifdef EXTRA_DEBUG - if (*key1 && param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS) - (*key1)->test_use_count(*key1); -#endif - } - } - tree1->keys_map= result_keys; - /* dispose index_merge if there is a "range" option */ - if (!result_keys.is_clear_all()) - { - tree1->merges.empty(); - DBUG_RETURN(tree1); - } - /* ok, both trees are index_merge trees */ + if (!tree1->merges.is_empty()) + imerge_list_and_tree(param, &tree1->merges, tree2); + if (!tree2->merges.is_empty()) + imerge_list_and_tree(param, &tree2->merges, tree1); + if (and_range_trees(param, tree1, tree2, tree1)) + DBUG_RETURN(tree1); imerge_list_and_list(&tree1->merges, &tree2->merges); + eliminate_single_tree_imerges(param, tree1); DBUG_RETURN(tree1); } /* - Check if two SEL_TREES can be combined into one (i.e. a single key range - read can be constructed for "cond_of_tree1 OR cond_of_tree2" ) without - using index_merge. + Eliminate single tree imerges in a SEL_TREE objects + + SYNOPSIS + eliminate_single_tree_imerges() + param Context info for the function + tree SEL_TREE where single tree imerges are to be eliminated + + DESCRIPTION + For each imerge in 'tree' that contains only one disjunct tree, i.e. + for any imerge of the form m=rt, the function performs and operation + the range part of tree, replaces rt the with the result of anding and + removes imerge m from the the merge part of 'tree'. + + RETURN VALUE + none */ -bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, - RANGE_OPT_PARAM* param) +static +void eliminate_single_tree_imerges(RANGE_OPT_PARAM *param, SEL_TREE *tree) { - key_map common_keys= tree1->keys_map; - DBUG_ENTER("sel_trees_can_be_ored"); - common_keys.intersect(tree2->keys_map); - - if (common_keys.is_clear_all()) - DBUG_RETURN(FALSE); - - /* trees have a common key, check if they refer to same key part */ - SEL_ARG **key1,**key2; - for (uint key_no=0; key_no < param->keys; key_no++) + SEL_IMERGE *imerge; + List merges= tree->merges; + List_iterator it(merges); + tree->merges.empty(); + while ((imerge= it++)) { - if (common_keys.is_set(key_no)) + if (imerge->trees+1 == imerge->trees_next) { - key1= tree1->keys + key_no; - key2= tree2->keys + key_no; - if ((*key1)->part == (*key2)->part) - { - DBUG_RETURN(TRUE); - } + tree= tree_and(param, tree, *imerge->trees); + it.remove(); } } - DBUG_RETURN(FALSE); + tree->merges= merges; +} + + +/* + For two trees check that there are indexes with ranges in both of them + + SYNOPSIS + sel_trees_have_common_keys() + param Context info for the function + tree1 SEL_TREE for the first tree + tree2 SEL_TREE for the second tree + common_keys OUT bitmap of all indexes with ranges in both trees + + DESCRIPTION + For two trees tree1 and tree1 the function checks if there are indexes + in their range parts such that SEL_ARG trees are defined for them in the + range parts of both trees. The function returns the bitmap of such + indexes in the parameter common_keys. + + RETURN + TRUE if there are such indexes (common_keys is nor empty) + FALSE otherwise +*/ + +static +bool sel_trees_have_common_keys(RANGE_OPT_PARAM* param, + SEL_TREE *tree1, SEL_TREE *tree2, + key_map *common_keys) +{ + *common_keys= tree1->keys_map; + common_keys->intersect(tree2->keys_map); + return !common_keys->is_clear_all(); } /* - Remove the trees that are not suitable for record retrieval. + Check whether range parts of two trees can be ored for some indexes + SYNOPSIS - param Range analysis parameter - tree Tree to be processed, tree->type is KEY or KEY_SMALLER + sel_trees_can_be_ored() + param Context info for the function + tree1 SEL_TREE for the first tree + tree2 SEL_TREE for the second tree + common_keys IN/OUT IN: bitmap of all indexes with SEL_ARG in both trees + OUT: bitmap of all indexes that can be ored + + DESCRIPTION + For two trees tree1 and tree2 and the bitmap common_keys containing + bits for indexes that have SEL_ARG trees in range parts of both trees + the function checks if there are indexes for which SEL_ARG trees can + be ored. Two SEL_ARG trees for the same index can be ored if the most + major components of the index used in these trees coincide. If the + SEL_ARG trees for an index cannot be ored the function clears the bit + for this index in the bitmap common_keys. + + The function does not verify that indexes marked in common_keys really + have SEL_ARG trees in both tree1 and tree2. It assumes that this is true. + + NOTE + The function sel_trees_can_be_ored is usually used in pair with the + function sel_trees_have_common_keys. + + RETURN + TRUE if there are indexes for which SEL_ARG trees can be ored + FALSE otherwise +*/ + +static +bool sel_trees_can_be_ored(RANGE_OPT_PARAM* param, + SEL_TREE *tree1, SEL_TREE *tree2, + key_map *common_keys) +{ + DBUG_ENTER("sel_trees_can_be_ored"); + if (!sel_trees_have_common_keys(param, tree1, tree2, common_keys)) + DBUG_RETURN(FALSE); + int key_no; + key_map::Iterator it(*common_keys); + while ((key_no= it++) != key_map::Iterator::BITMAP_END) + { + DBUG_ASSERT(tree1->keys[key_no] && tree2->keys[key_no]); + /* Trees have a common key, check if they refer to the same key part */ + if (tree1->keys[key_no]->part != tree2->keys[key_no]->part) + common_keys->clear_bit(key_no); + } + DBUG_RETURN(!common_keys->is_clear_all()); +} + +/* + Check whether range parts of two trees must be ored for some indexes + + SYNOPSIS + sel_trees_must_be_ored() + param Context info for the function + tree1 SEL_TREE for the first tree + tree2 SEL_TREE for the second tree + ordable_keys bitmap of SEL_ARG trees that can be ored + + DESCRIPTION + For two trees tree1 and tree2 and the bitmap ordable_keys containing + bits for indexes that have SEL_ARG trees in range parts of both trees + and these SEL_ARG trees can be ored the function checks if there are + indexes for which SEL_ARG trees must be ored. Two SEL_ARG trees for the + same index must be ored if all indexes for which SEL_SRG trees from the + range parts of tree1 anf tree2 that can be ored have the same field as + their major index component. + + NOTE + The function sel_trees_must_be_ored as a rule is used in pair with the + function sel_trees_can_be_ored. + + RETURN + TRUE if there are indexes for which SEL_ARG trees must be ored + FALSE otherwise +*/ + +static +bool sel_trees_must_be_ored(RANGE_OPT_PARAM* param, + SEL_TREE *tree1, SEL_TREE *tree2, + key_map oredable_keys) +{ + key_map tmp; + DBUG_ENTER("sel_trees_must_be_ored"); + + tmp= tree1->keys_map; + tmp.merge(tree2->keys_map); + tmp.subtract(oredable_keys); + if (!tmp.is_clear_all()) + DBUG_RETURN(FALSE); + + Field *field= 0; + uint part; + int key_no; + key_map::Iterator it(oredable_keys); + while ((key_no= it++) != key_map::Iterator::BITMAP_END) + { + SEL_ARG *key1= tree1->keys[key_no]; + if (!field) + { + field= key1->field; + part= key1->part; + } + else if (!field->eq(key1->field)) + DBUG_RETURN(FALSE); + } + DBUG_RETURN(TRUE); +} + + +/* + Remove the trees that are not suitable for record retrieval + + SYNOPSIS + remove_nonrange_trees() + param Context info for the function + tree Tree to be processed, tree->type is KEY or KEY_SMALLER DESCRIPTION This function walks through tree->keys[] and removes the SEL_ARG* trees @@ -6163,41 +7067,34 @@ bool sel_trees_can_be_ored(SEL_TREE *tree1, SEL_TREE *tree2, A SEL_ARG* tree cannot be used to construct quick select if it has tree->part != 0. (e.g. it could represent "keypart2 < const"). - - WHY THIS FUNCTION IS NEEDED Normally we allow construction of SEL_TREE objects that have SEL_ARG - trees that do not allow quick range select construction. For example for - " keypart1=1 AND keypart2=2 " the execution will proceed as follows: + trees that do not allow quick range select construction. + For example: + for " keypart1=1 AND keypart2=2 " the execution will proceed as follows: tree1= SEL_TREE { SEL_ARG{keypart1=1} } tree2= SEL_TREE { SEL_ARG{keypart2=2} } -- can't make quick range select from this call tree_and(tree1, tree2) -- this joins SEL_ARGs into a usable SEL_ARG tree. - - There is an exception though: when we construct index_merge SEL_TREE, - any SEL_ARG* tree that cannot be used to construct quick range select can - be removed, because current range analysis code doesn't provide any way - that tree could be later combined with another tree. - Consider an example: we should not construct - st1 = SEL_TREE { - merges = SEL_IMERGE { - SEL_TREE(t.key1part1 = 1), - SEL_TREE(t.key2part2 = 2) -- (*) - } - }; - because - - (*) cannot be used to construct quick range select, - - There is no execution path that would cause (*) to be converted to - a tree that could be used. - The latter is easy to verify: first, notice that the only way to convert - (*) into a usable tree is to call tree_and(something, (*)). - - Second look at what tree_and/tree_or function would do when passed a - SEL_TREE that has the structure like st1 tree has, and conlcude that - tree_and(something, (*)) will not be called. + Another example: + tree3= SEL_TREE { SEL_ARG{key1part1 = 1} } + tree4= SEL_TREE { SEL_ARG{key2part2 = 2} } -- can't make quick range select + from this + call tree_or(tree3, tree4) -- creates a SEL_MERGE ot of which no index + merge can be constructed, but it is potentially useful, as anding it with + tree5= SEL_TREE { SEL_ARG{key2part1 = 3} } creates an index merge that + represents the formula + key1part1=1 AND key2part1=3 OR key2part1=3 AND key2part2=2 + for which an index merge can be built. + Any final SEL_TREE may contains SEL_ARG trees for which no quick select + can be built. Such SEL_ARG trees should be removed from the range part + before different range scans are evaluated. Such SEL_ARG trees also should + be removed from all range trees of each index merge before different + possible index merge plans are evaluated. + RETURN 0 Ok, some suitable trees left 1 No tree->keys[] left. @@ -6223,6 +7120,74 @@ static bool remove_nonrange_trees(RANGE_OPT_PARAM *param, SEL_TREE *tree) } +/* + Build a SEL_TREE for a disjunction out of such trees for the disjuncts + + SYNOPSIS + tree_or() + param Context info for the operation + tree1 SEL_TREE for the first disjunct + tree2 SEL_TREE for the second disjunct + + DESCRIPTION + This function builds a tree for the formula (A OR B) out of the trees + tree1 and tree2 that has been built for the formulas A and B respectively. + + In a general case + tree1 represents the formula RT1 AND MT1, + where RT1=R1_1 AND ... AND R1_k1, MT1=M1_1 AND ... AND M1_l1; + tree2 represents the formula RT2 AND MT2 + where RT2=R2_1 AND ... AND R2_k2, MT2=M2_1 and ... and M2_l2. + + The function constructs the result tree according the formula + (RT1 OR RT2) AND (MT1 OR RT1) AND (MT2 OR RT2) AND (MT1 OR MT2) + that is equivalent to the formula (RT1 AND MT1) OR (RT2 AND MT2). + + To limit the number of produced imerges the function considers + a weaker formula than the original one: + (RT1 AND M1_1) OR (RT2 AND M2_1) + that is equivalent to: + (RT1 OR RT2) (1) + AND + (M1_1 OR M2_1) (2) + AND + (M1_1 OR RT2) (3) + AND + (M2_1 OR RT1) (4) + + For the first conjunct (1) the function builds a tree with a range part + and, possibly, one imerge. For the other conjuncts (2-4)the function + produces sets of imerges. All constructed imerges are included into the + result tree. + + For the formula (1) the function produces the tree representing a formula + of the structure RT [AND M], such that: + - the range tree rt contains the result of oring SEL_ARG trees from rt1 + and rt2 + - the imerge m consists of two range trees rt1 and rt2. + The imerge m is added if it's not true that rt1 and rt2 must be ored + If rt1 and rt2 can't be ored rt is empty and only m is produced for (1). + + To produce imerges for the formula (2) the function calls the function + imerge_list_or_list passing it the merge parts of tree1 and tree2 as + parameters. + + To produce imerges for the formula (3) the function calls the function + imerge_list_or_tree passing it the imerge m1_1 and the range tree rt2 as + parameters. Similarly, to produce imerges for the formula (4) the function + calls the function imerge_list_or_tree passing it the imerge m2_1 and the + range tree rt1. + + If rt1 is empty then the trees for (1) and (4) are empty. + If rt2 is empty then the trees for (1) and (3) are empty. + If mt1 is empty then the trees for (2) and (3) are empty. + If mt2 is empty then the trees for (2) and (4) are empty. + + RETURN + The result tree for the operation if a success + 0 - otherwise +*/ + static SEL_TREE * tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2) { @@ -6238,74 +7203,100 @@ tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2) if (tree2->type == SEL_TREE::MAYBE) DBUG_RETURN(tree2); - SEL_TREE *result= 0; - key_map result_keys; - result_keys.clear_all(); - if (sel_trees_can_be_ored(tree1, tree2, param)) + SEL_TREE *result= NULL; + key_map result_keys; + key_map ored_keys; + SEL_TREE *rtree[2]= {NULL,NULL}; + SEL_IMERGE *imerge[2]= {NULL, NULL}; + bool no_ranges1= tree1->without_ranges(); + bool no_ranges2= tree2->without_ranges(); + bool no_merges1= tree1->without_imerges(); + bool no_merges2= tree2->without_imerges(); + if (!no_ranges1 && !no_merges2) { - /* Join the trees key per key */ - SEL_ARG **key1,**key2,**end; - for (key1= tree1->keys,key2= tree2->keys,end= key1+param->keys ; - key1 != end ; key1++,key2++) - { - *key1=key_or(param, *key1, *key2); - if (*key1) - { - result=tree1; // Added to tree1 - result_keys.set_bit(key1 - tree1->keys); -#ifdef EXTRA_DEBUG - if (param->alloced_sel_args < SEL_ARG::MAX_SEL_ARGS) - (*key1)->test_use_count(*key1); -#endif - } - } - if (result) - result->keys_map= result_keys; + rtree[0]= new SEL_TREE(tree1, TRUE, param); + imerge[1]= new SEL_IMERGE(tree2->merges.head(), 0, param); } - else + if (!no_ranges2 && !no_merges1) { - /* ok, two trees have KEY type but cannot be used without index merge */ - if (tree1->merges.is_empty() && tree2->merges.is_empty()) + rtree[1]= new SEL_TREE(tree2, TRUE, param); + imerge[0]= new SEL_IMERGE(tree1->merges.head(), 0, param); + } + bool no_imerge_from_ranges= FALSE; + if (!(result= new SEL_TREE())) + DBUG_RETURN(result); + + /* Build the range part of the tree for the formula (1) */ + if (sel_trees_can_be_ored(param, tree1, tree2, &ored_keys)) + { + bool must_be_ored= sel_trees_must_be_ored(param, tree1, tree2, ored_keys); + no_imerge_from_ranges= must_be_ored; + key_map::Iterator it(ored_keys); + int key_no; + while ((key_no= it++) != key_map::Iterator::BITMAP_END) { - if (param->remove_jump_scans) + SEL_ARG *key1= tree1->keys[key_no]; + SEL_ARG *key2= tree2->keys[key_no]; + if (!must_be_ored) { - bool no_trees= remove_nonrange_trees(param, tree1); - no_trees= no_trees || remove_nonrange_trees(param, tree2); - if (no_trees) - DBUG_RETURN(new SEL_TREE(SEL_TREE::ALWAYS)); + key1->incr_refs(); + key2->incr_refs(); } - SEL_IMERGE *merge; - /* both trees are "range" trees, produce new index merge structure */ - if (!(result= new SEL_TREE()) || !(merge= new SEL_IMERGE()) || - (result->merges.push_back(merge)) || - (merge->or_sel_tree(param, tree1)) || - (merge->or_sel_tree(param, tree2))) - result= NULL; - else - result->type= tree1->type; + if ((result->keys[key_no]= key_or(param, key1, key2))) + result->keys_map.set_bit(key_no); } - else if (!tree1->merges.is_empty() && !tree2->merges.is_empty()) - { - if (imerge_list_or_list(param, &tree1->merges, &tree2->merges)) - result= new SEL_TREE(SEL_TREE::ALWAYS); - else - result= tree1; - } - else - { - /* one tree is index merge tree and another is range tree */ - if (tree1->merges.is_empty()) - swap_variables(SEL_TREE*, tree1, tree2); + result->type= tree1->type; + } - if (param->remove_jump_scans && remove_nonrange_trees(param, tree2)) - DBUG_RETURN(new SEL_TREE(SEL_TREE::ALWAYS)); - /* add tree2 to tree1->merges, checking if it collapses to ALWAYS */ - if (imerge_list_or_tree(param, &tree1->merges, tree2)) - result= new SEL_TREE(SEL_TREE::ALWAYS); - else - result= tree1; - } + if (no_imerge_from_ranges && no_merges1 && no_merges2) + { + if (result->keys_map.is_clear_all()) + result->type= SEL_TREE::ALWAYS; + DBUG_RETURN(result); } + + SEL_IMERGE *imerge_from_ranges; + if (!(imerge_from_ranges= new SEL_IMERGE())) + result= NULL; + else if (!no_ranges1 && !no_ranges2 && !no_imerge_from_ranges) + { + /* Build the imerge part of the tree for the formula (1) */ + SEL_TREE *rt1= tree1; + SEL_TREE *rt2= tree2; + if (!no_merges1) + rt1= new SEL_TREE(tree1, TRUE, param); + if (!no_merges2) + rt2= new SEL_TREE(tree2, TRUE, param); + if (!rt1 || !rt2 || + result->merges.push_back(imerge_from_ranges) || + imerge_from_ranges->or_sel_tree(param, rt1) || + imerge_from_ranges->or_sel_tree(param, rt2)) + result= NULL; + } + if (!result) + DBUG_RETURN(result); + + result->type= tree1->type; + + if (!no_merges1 && !no_merges2 && + !imerge_list_or_list(param, &tree1->merges, &tree2->merges)) + { + /* Build the imerges for the formula (2) */ + imerge_list_and_list(&result->merges, &tree1->merges); + } + + /* Build the imerges for the formulas (3) and (4) */ + for (uint i=0; i < 2; i++) + { + List merges; + SEL_TREE *rt= rtree[i]; + SEL_IMERGE *im= imerge[1-i]; + + if (rt && im && !merges.push_back(im) && + !imerge_list_or_tree(param, &merges, rt)) + imerge_list_and_list(&result->merges, &merges); + } + DBUG_RETURN(result); } @@ -6558,7 +7549,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2) { swap_variables(SEL_ARG *,key1,key2); } - if (key1->use_count > 0 || !(key1=key1->clone_tree(param))) + if (key1->use_count > 0 && !(key1=key1->clone_tree(param))) return 0; // OOM } @@ -7237,11 +8228,7 @@ static ulong count_key_part_usage(SEL_ARG *root, SEL_ARG *key) void SEL_ARG::test_use_count(SEL_ARG *root) { uint e_count=0; - if (this == root && use_count != 1) - { - sql_print_information("Use_count: Wrong count %lu for root",use_count); - return; - } + if (this->type != SEL_ARG::KEY_RANGE) return; for (SEL_ARG *pos=first(); pos ; pos=pos->next) @@ -7344,12 +8331,13 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree, bool update_tbl_stats) param->table->quick_n_ranges[key]= param->n_ranges; param->table->quick_condition_rows= min(param->table->quick_condition_rows, records); + param->table->quick_rows[key]= records; } /* Need to save quick_rows in any case as it is used when calculating cost of ROR intersection: */ - param->table->quick_rows[key]=records; + param->quick_rows[key]= records; if (cpk_scan) param->is_ror_scan= TRUE; } diff --git a/sql/sql_list.h b/sql/sql_list.h index 93cdd20c299..cbe94b9f226 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -168,6 +168,14 @@ public: { if (!list->is_empty()) { +#if 0 +#else + if (is_empty()) + { + *this= *list; + return; + } +#endif *last= list->first; last= list->last; elements+= list->elements; From 9d39a137619a43fbc1d293e720eba02d1a0b572c Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 17 Oct 2009 11:40:46 -0700 Subject: [PATCH 02/33] Changed test cases to make results for innodb platform independent. --- mysql-test/r/range_vs_index_merge.result | 70 ++++++------------ .../r/range_vs_index_merge_innodb.result | 72 ++++++------------- mysql-test/t/range_vs_index_merge.test | 38 +++++----- 3 files changed, 63 insertions(+), 117 deletions(-) mode change 100755 => 100644 mysql-test/r/range_vs_index_merge.result mode change 100755 => 100644 mysql-test/r/range_vs_index_merge_innodb.result diff --git a/mysql-test/r/range_vs_index_merge.result b/mysql-test/r/range_vs_index_merge.result old mode 100755 new mode 100644 index 06c5bd4f09e..a2677471f55 --- a/mysql-test/r/range_vs_index_merge.result +++ b/mysql-test/r/range_vs_index_merge.result @@ -176,9 +176,9 @@ SELECT * FROM City WHERE (Name < 'Ac'); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Name Name 35 NULL 13 Using where EXPLAIN -SELECT * FROM City WHERE (Name < 'C'); +SELECT * FROM City WHERE (Name < 'Bb'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Name Name 35 NULL 325 Using where +1 SIMPLE City range Name Name 35 NULL 208 Using where EXPLAIN SELECT * FROM City WHERE (Country > 'A' AND Country < 'B'); id select_type table type possible_keys key key_len ref rows Extra @@ -188,9 +188,9 @@ SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'Pb'); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Name Name 35 NULL 39 Using where EXPLAIN -SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'T'); +SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'S'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Name Name 35 NULL 468 Using where +1 SIMPLE City range Name Name 35 NULL 221 Using where EXPLAIN SELECT * FROM City WHERE (Population > 101000 AND Population < 110000); id select_type table type possible_keys key key_len ref rows Extra @@ -208,19 +208,19 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR -(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge Population,Country,Name Name,Population 35,4 NULL 50 Using sort_union(Name,Population); Using where EXPLAIN SELECT * FROM City -WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR +WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge Population,Country,Name Country,Name 3,35 NULL 143 Using sort_union(Country,Name); Using where EXPLAIN SELECT * FROM City -WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR -(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge Population,Country,Name Country,Population 3,4 NULL 141 Using sort_union(Country,Population); Using where SELECT * FROM City USE INDEX () @@ -243,39 +243,33 @@ ID Name Country Population 189 Parakou BEN 103577 SELECT * FROM City USE INDEX () WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR -(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); ID Name Country Population 65 Abu Dhabi ARE 398695 168 Pabna BGD 103277 189 Parakou BEN 103577 -914 Sekondi-Takoradi GHA 103653 1003 Pemalang IDN 103500 2663 Río Bravo MEX 103901 SELECT * FROM City WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR -(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); ID Name Country Population 65 Abu Dhabi ARE 398695 168 Pabna BGD 103277 189 Parakou BEN 103577 -914 Sekondi-Takoradi GHA 103653 1003 Pemalang IDN 103500 2663 Río Bravo MEX 103901 SELECT * FROM City USE INDEX () -WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR +WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); ID Name Country Population 55 Andorra la Vella AND 21189 -59 Benguela AGO 128300 65 Abu Dhabi ARE 398695 67 al-Ayn ARE 225970 68 Ajman ARE 114395 -69 Buenos Aires ARG 2982146 75 Almirante Brown ARG 538918 85 Avellaneda ARG 353046 -93 Berazategui ARG 276916 96 Bahía Blanca ARG 239810 -132 Brisbane AUS 1291117 134 Adelaide AUS 978100 144 Baku AZE 1787800 168 Pabna BGD 103277 @@ -283,20 +277,16 @@ ID Name Country Population 750 Paarl ZAF 105768 2865 Pak Pattan PAK 107800 SELECT * FROM City -WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR +WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); ID Name Country Population 55 Andorra la Vella AND 21189 -59 Benguela AGO 128300 65 Abu Dhabi ARE 398695 67 al-Ayn ARE 225970 68 Ajman ARE 114395 -69 Buenos Aires ARG 2982146 75 Almirante Brown ARG 538918 85 Avellaneda ARG 353046 -93 Berazategui ARG 276916 96 Bahía Blanca ARG 239810 -132 Brisbane AUS 1291117 134 Adelaide AUS 978100 144 Baku AZE 1787800 168 Pabna BGD 103277 @@ -304,47 +294,37 @@ ID Name Country Population 750 Paarl ZAF 105768 2865 Pak Pattan PAK 107800 SELECT * FROM City USE INDEX () -WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR -(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); ID Name Country Population 55 Andorra la Vella AND 21189 -59 Benguela AGO 128300 65 Abu Dhabi ARE 398695 67 al-Ayn ARE 225970 68 Ajman ARE 114395 -69 Buenos Aires ARG 2982146 75 Almirante Brown ARG 538918 85 Avellaneda ARG 353046 -93 Berazategui ARG 276916 96 Bahía Blanca ARG 239810 -132 Brisbane AUS 1291117 134 Adelaide AUS 978100 144 Baku AZE 1787800 168 Pabna BGD 103277 189 Parakou BEN 103577 -914 Sekondi-Takoradi GHA 103653 1003 Pemalang IDN 103500 2663 Río Bravo MEX 103901 SELECT * FROM City -WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR -(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); ID Name Country Population 55 Andorra la Vella AND 21189 -59 Benguela AGO 128300 65 Abu Dhabi ARE 398695 67 al-Ayn ARE 225970 68 Ajman ARE 114395 -69 Buenos Aires ARG 2982146 75 Almirante Brown ARG 538918 85 Avellaneda ARG 353046 -93 Berazategui ARG 276916 96 Bahía Blanca ARG 239810 -132 Brisbane AUS 1291117 134 Adelaide AUS 978100 144 Baku AZE 1787800 168 Pabna BGD 103277 189 Parakou BEN 103577 -914 Sekondi-Takoradi GHA 103653 1003 Pemalang IDN 103500 2663 Río Bravo MEX 103901 EXPLAIN @@ -651,9 +631,9 @@ SELECT * FROM City WHERE Country < 'AGO'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Country Country 3 NULL 6 Using where EXPLAIN -SELECT * FROM City WHERE Name BETWEEN 'P' AND 'T'; +SELECT * FROM City WHERE Name BETWEEN 'P' AND 'S'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Name Name 35 NULL 468 Using where +1 SIMPLE City range Name Name 35 NULL 221 Using where EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'P' AND 'Pb'; id select_type table type possible_keys key key_len ref rows Extra @@ -673,7 +653,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE ((Population > 101000 AND Population < 102000) AND -(Country < 'C' OR Name BETWEEN 'P' AND 'T')) OR +(Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR ((ID BETWEEN 3400 AND 3800) AND (Country < 'AGO' OR Name LIKE 'Pa%')); id select_type table type possible_keys key key_len ref rows Extra @@ -688,7 +668,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge PRIMARY,Population,Country,Name Country,Name,PRIMARY 3,35,4 NULL 56 Using sort_union(Country,Name,PRIMARY); Using where SELECT * FROM City USE INDEX () WHERE ((Population > 101000 AND Population < 102000) AND -(Country < 'C' OR Name BETWEEN 'P' AND 'T')) OR +(Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR ((ID BETWEEN 3400 AND 3800) AND (Country < 'AGO' OR Name LIKE 'Pa%')); ID Name Country Population @@ -697,15 +677,11 @@ ID Name Country Population 417 Itaituba BRA 101320 418 Araras BRA 101046 751 Potchefstroom ZAF 101817 -1752 Sakata JPN 101651 -1851 Saint John´s CAN 101936 -1853 Saanich CAN 101388 2909 Puno PER 101578 3463 Pavlograd UKR 127000 -4030 Sandy USA 101853 SELECT * FROM City WHERE ((Population > 101000 AND Population < 102000) AND -(Country < 'C' OR Name BETWEEN 'P' AND 'T')) OR +(Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR ((ID BETWEEN 3400 AND 3800) AND (Country < 'AGO' OR Name LIKE 'Pa%')); ID Name Country Population @@ -714,12 +690,8 @@ ID Name Country Population 417 Itaituba BRA 101320 418 Araras BRA 101046 751 Potchefstroom ZAF 101817 -1752 Sakata JPN 101651 -1851 Saint John´s CAN 101936 -1853 Saanich CAN 101388 2909 Puno PER 101578 3463 Pavlograd UKR 127000 -4030 Sandy USA 101853 SELECT * FROM City USE INDEX () WHERE ((Population > 101000 AND Population < 110000) AND (Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result old mode 100755 new mode 100644 index 2e949bd47ce..8250c91097e --- a/mysql-test/r/range_vs_index_merge_innodb.result +++ b/mysql-test/r/range_vs_index_merge_innodb.result @@ -43,7 +43,7 @@ EXPLAIN SELECT * FROM City WHERE (Population >= 100000 OR Name LIKE 'P%' OR Population < 100000); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City ALL Population,Name NULL NULL NULL 4249 Using where +1 SIMPLE City ALL Population,Name NULL NULL NULL 4079 Using where EXPLAIN SELECT * FROM City WHERE (Population >= 100000 OR Name LIKE 'P%') AND Country='CAN' OR @@ -177,9 +177,9 @@ SELECT * FROM City WHERE (Name < 'Ac'); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Name Name 35 NULL 23 Using where EXPLAIN -SELECT * FROM City WHERE (Name < 'C'); +SELECT * FROM City WHERE (Name < 'Bb'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City ALL Name NULL NULL NULL 4249 Using where +1 SIMPLE City range Name Name 35 NULL 373 Using where EXPLAIN SELECT * FROM City WHERE (Country > 'A' AND Country < 'B'); id select_type table type possible_keys key key_len ref rows Extra @@ -189,9 +189,9 @@ SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'Pb'); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Name Name 35 NULL 71 Using where EXPLAIN -SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'T'); +SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'S'); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City ALL Name NULL NULL NULL 4249 Using where +1 SIMPLE City range Name Name 35 NULL 384 Using where EXPLAIN SELECT * FROM City WHERE (Population > 101000 AND Population < 110000); id select_type table type possible_keys key key_len ref rows Extra @@ -209,19 +209,19 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR -(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge Population,Country,Name Name,Population 35,4 NULL 59 Using sort_union(Name,Population); Using where EXPLAIN SELECT * FROM City -WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR +WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge Population,Country,Name Country,Name 3,35 NULL 177 Using sort_union(Country,Name); Using where EXPLAIN SELECT * FROM City -WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR -(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge Population,Country,Name Country,Population 3,4 NULL 142 Using sort_union(Country,Population); Using where SELECT * FROM City USE INDEX () @@ -244,39 +244,33 @@ ID Name Country Population 189 Parakou BEN 103577 SELECT * FROM City USE INDEX () WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR -(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); ID Name Country Population 65 Abu Dhabi ARE 398695 168 Pabna BGD 103277 189 Parakou BEN 103577 -914 Sekondi-Takoradi GHA 103653 1003 Pemalang IDN 103500 2663 Río Bravo MEX 103901 SELECT * FROM City WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR -(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); ID Name Country Population 65 Abu Dhabi ARE 398695 168 Pabna BGD 103277 189 Parakou BEN 103577 -914 Sekondi-Takoradi GHA 103653 1003 Pemalang IDN 103500 2663 Río Bravo MEX 103901 SELECT * FROM City USE INDEX () -WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR +WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); ID Name Country Population 55 Andorra la Vella AND 21189 -59 Benguela AGO 128300 65 Abu Dhabi ARE 398695 67 al-Ayn ARE 225970 68 Ajman ARE 114395 -69 Buenos Aires ARG 2982146 75 Almirante Brown ARG 538918 85 Avellaneda ARG 353046 -93 Berazategui ARG 276916 96 Bahía Blanca ARG 239810 -132 Brisbane AUS 1291117 134 Adelaide AUS 978100 144 Baku AZE 1787800 168 Pabna BGD 103277 @@ -284,20 +278,16 @@ ID Name Country Population 750 Paarl ZAF 105768 2865 Pak Pattan PAK 107800 SELECT * FROM City -WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR +WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); ID Name Country Population 55 Andorra la Vella AND 21189 -59 Benguela AGO 128300 65 Abu Dhabi ARE 398695 67 al-Ayn ARE 225970 68 Ajman ARE 114395 -69 Buenos Aires ARG 2982146 75 Almirante Brown ARG 538918 85 Avellaneda ARG 353046 -93 Berazategui ARG 276916 96 Bahía Blanca ARG 239810 -132 Brisbane AUS 1291117 134 Adelaide AUS 978100 144 Baku AZE 1787800 168 Pabna BGD 103277 @@ -305,47 +295,37 @@ ID Name Country Population 750 Paarl ZAF 105768 2865 Pak Pattan PAK 107800 SELECT * FROM City USE INDEX () -WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR -(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); ID Name Country Population 55 Andorra la Vella AND 21189 -59 Benguela AGO 128300 65 Abu Dhabi ARE 398695 67 al-Ayn ARE 225970 68 Ajman ARE 114395 -69 Buenos Aires ARG 2982146 75 Almirante Brown ARG 538918 85 Avellaneda ARG 353046 -93 Berazategui ARG 276916 96 Bahía Blanca ARG 239810 -132 Brisbane AUS 1291117 134 Adelaide AUS 978100 144 Baku AZE 1787800 168 Pabna BGD 103277 189 Parakou BEN 103577 -914 Sekondi-Takoradi GHA 103653 1003 Pemalang IDN 103500 2663 Río Bravo MEX 103901 SELECT * FROM City -WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR -(Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); +WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR +(Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); ID Name Country Population 55 Andorra la Vella AND 21189 -59 Benguela AGO 128300 65 Abu Dhabi ARE 398695 67 al-Ayn ARE 225970 68 Ajman ARE 114395 -69 Buenos Aires ARG 2982146 75 Almirante Brown ARG 538918 85 Avellaneda ARG 353046 -93 Berazategui ARG 276916 96 Bahía Blanca ARG 239810 -132 Brisbane AUS 1291117 134 Adelaide AUS 978100 144 Baku AZE 1787800 168 Pabna BGD 103277 189 Parakou BEN 103577 -914 Sekondi-Takoradi GHA 103653 1003 Pemalang IDN 103500 2663 Río Bravo MEX 103901 EXPLAIN @@ -652,9 +632,9 @@ SELECT * FROM City WHERE Country < 'AGO'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Country Country 3 NULL 5 Using where EXPLAIN -SELECT * FROM City WHERE Name BETWEEN 'P' AND 'T'; +SELECT * FROM City WHERE Name BETWEEN 'P' AND 'S'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City ALL Name NULL NULL NULL 4249 Using where +1 SIMPLE City range Name Name 35 NULL 384 Using where EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'P' AND 'Pb'; id select_type table type possible_keys key key_len ref rows Extra @@ -674,7 +654,7 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE ((Population > 101000 AND Population < 102000) AND -(Country < 'C' OR Name BETWEEN 'P' AND 'T')) OR +(Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR ((ID BETWEEN 3400 AND 3800) AND (Country < 'AGO' OR Name LIKE 'Pa%')); id select_type table type possible_keys key key_len ref rows Extra @@ -689,7 +669,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge PRIMARY,Population,Country,Name Country,Name,PRIMARY 3,35,4 NULL 87 Using sort_union(Country,Name,PRIMARY); Using where SELECT * FROM City USE INDEX () WHERE ((Population > 101000 AND Population < 102000) AND -(Country < 'C' OR Name BETWEEN 'P' AND 'T')) OR +(Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR ((ID BETWEEN 3400 AND 3800) AND (Country < 'AGO' OR Name LIKE 'Pa%')); ID Name Country Population @@ -698,15 +678,11 @@ ID Name Country Population 417 Itaituba BRA 101320 418 Araras BRA 101046 751 Potchefstroom ZAF 101817 -1752 Sakata JPN 101651 -1851 Saint John´s CAN 101936 -1853 Saanich CAN 101388 2909 Puno PER 101578 3463 Pavlograd UKR 127000 -4030 Sandy USA 101853 SELECT * FROM City WHERE ((Population > 101000 AND Population < 102000) AND -(Country < 'C' OR Name BETWEEN 'P' AND 'T')) OR +(Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR ((ID BETWEEN 3400 AND 3800) AND (Country < 'AGO' OR Name LIKE 'Pa%')); ID Name Country Population @@ -715,12 +691,8 @@ ID Name Country Population 417 Itaituba BRA 101320 418 Araras BRA 101046 751 Potchefstroom ZAF 101817 -1752 Sakata JPN 101651 -1851 Saint John´s CAN 101936 -1853 Saanich CAN 101388 2909 Puno PER 101578 3463 Pavlograd UKR 127000 -4030 Sandy USA 101853 SELECT * FROM City USE INDEX () WHERE ((Population > 101000 AND Population < 110000) AND (Country < 'AGO' OR Name BETWEEN 'P' AND 'Pb')) OR diff --git a/mysql-test/t/range_vs_index_merge.test b/mysql-test/t/range_vs_index_merge.test index a4511ccfd19..3e4614202b3 100755 --- a/mysql-test/t/range_vs_index_merge.test +++ b/mysql-test/t/range_vs_index_merge.test @@ -35,6 +35,8 @@ ANALYZE TABLE City; # The following 4 queries are added for code coverage +#the exptected # of rows differ on 32-bit and 64-bit platforms for innodb +--replace_column 9 4079 EXPLAIN SELECT * FROM City WHERE (Population >= 100000 OR Name LIKE 'P%' OR Population < 100000); @@ -113,13 +115,13 @@ SELECT * FROM City EXPLAIN SELECT * FROM City WHERE (Name < 'Ac'); EXPLAIN -SELECT * FROM City WHERE (Name < 'C'); +SELECT * FROM City WHERE (Name < 'Bb'); EXPLAIN SELECT * FROM City WHERE (Country > 'A' AND Country < 'B'); EXPLAIN SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'Pb'); EXPLAIN -SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'T'); +SELECT * FROM City WHERE (Name BETWEEN 'P' AND 'S'); EXPLAIN SELECT * FROM City WHERE (Population > 101000 AND Population < 110000); EXPLAIN @@ -143,17 +145,17 @@ SELECT * FROM City EXPLAIN SELECT * FROM City WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR - (Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); + (Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); EXPLAIN SELECT * FROM City - WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR + WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); EXPLAIN SELECT * FROM City - WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR - (Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); + WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); # The following 8 queries check that the plans # for the previous 4 plans are valid @@ -168,27 +170,27 @@ SELECT * FROM City SELECT * FROM City USE INDEX () WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR - (Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); + (Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); SELECT * FROM City WHERE (Name < 'Ac' AND (Country > 'A' AND Country < 'B')) OR - (Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); + (Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); SELECT * FROM City USE INDEX () - WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR + WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); SELECT * FROM City - WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR + WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR (Name BETWEEN 'P' AND 'Pb' AND (Population > 101000 AND Population < 110000)); SELECT * FROM City USE INDEX () - WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR - (Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); + WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); SELECT * FROM City - WHERE (Name < 'C' AND (Country > 'A' AND Country < 'B')) OR - (Name BETWEEN 'P' AND 'T' AND (Population > 103000 AND Population < 104000)); + WHERE (Name < 'Bb' AND (Country > 'A' AND Country < 'B')) OR + (Name BETWEEN 'P' AND 'S' AND (Population > 103000 AND Population < 104000)); # The output of the next 6 commands tells us about selectivities @@ -280,7 +282,7 @@ SELECT * FROM City WHERE Country < 'C'; EXPLAIN SELECT * FROM City WHERE Country < 'AGO'; EXPLAIN -SELECT * FROM City WHERE Name BETWEEN 'P' AND 'T'; +SELECT * FROM City WHERE Name BETWEEN 'P' AND 'S'; EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'P' AND 'Pb'; EXPLAIN @@ -302,7 +304,7 @@ SELECT * FROM City WHERE Name LIKE 'P%'; EXPLAIN SELECT * FROM City WHERE ((Population > 101000 AND Population < 102000) AND - (Country < 'C' OR Name BETWEEN 'P' AND 'T')) OR + (Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR ((ID BETWEEN 3400 AND 3800) AND (Country < 'AGO' OR Name LIKE 'Pa%')); @@ -318,13 +320,13 @@ SELECT * FROM City SELECT * FROM City USE INDEX () WHERE ((Population > 101000 AND Population < 102000) AND - (Country < 'C' OR Name BETWEEN 'P' AND 'T')) OR + (Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR ((ID BETWEEN 3400 AND 3800) AND (Country < 'AGO' OR Name LIKE 'Pa%')); SELECT * FROM City WHERE ((Population > 101000 AND Population < 102000) AND - (Country < 'C' OR Name BETWEEN 'P' AND 'T')) OR + (Country < 'C' OR Name BETWEEN 'P' AND 'S')) OR ((ID BETWEEN 3400 AND 3800) AND (Country < 'AGO' OR Name LIKE 'Pa%')); From 27191a30c0bec853a418637c20f268b1dd408ccd Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 29 Oct 2009 11:49:58 -0700 Subject: [PATCH 03/33] Replaced a lame implementation of the function sel_trees_must_be_ored that blocked building index merge plans for the queries with where conditions of the form (key1|2_p1=c AND range(key1_p2)) OR (key1|2_p1=c AND range(key2_p2)). The problem was discovered by Sergey Petrunia when he reviewed the patch for WL#24. Added new test cases. One of them failed to produce an index merge plan before the patch was applied. --- mysql-test/r/range_vs_index_merge.result | 62 +++++++++++++++++ .../r/range_vs_index_merge_innodb.result | 62 +++++++++++++++++ mysql-test/t/range_vs_index_merge.test | 45 +++++++++++++ sql/opt_range.cc | 66 +++++++++++++------ 4 files changed, 214 insertions(+), 21 deletions(-) diff --git a/mysql-test/r/range_vs_index_merge.result b/mysql-test/r/range_vs_index_merge.result index a2677471f55..0563a0e491f 100644 --- a/mysql-test/r/range_vs_index_merge.result +++ b/mysql-test/r/range_vs_index_merge.result @@ -1076,6 +1076,68 @@ ID BETWEEN 3500 AND 3800) AND Country='USA' AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300); ID Name Country Population 3798 Phoenix USA 1321045 +DROP INDEX Population ON City; +DROP INDEX Name ON City; +EXPLAIN +SELECT * FROM City +WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR +Country='USA' AND Name LIKE 'Pa%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge Country,CountryPopulation,CountryName CountryPopulation,CountryName 7,38 NULL 10 Using sort_union(CountryPopulation,CountryName); Using where +SELECT * FROM City USE INDEX() +WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR +Country='USA' AND Name LIKE 'Pa%'; +ID Name Country Population +3932 Paterson USA 149222 +3943 Pasadena USA 141674 +3953 Pasadena USA 133936 +3967 Paradise USA 124682 +3986 Palmdale USA 116670 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City +WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR +Country='USA' AND Name LIKE 'Pa%'; +ID Name Country Population +3932 Paterson USA 149222 +3943 Pasadena USA 141674 +3953 Pasadena USA 133936 +3967 Paradise USA 124682 +3986 Palmdale USA 116670 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +EXPLAIN +SELECT * FROM City +WHERE Country='USA' AND +(Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge Country,CountryPopulation,CountryName CountryPopulation,CountryName 7,38 NULL 10 Using sort_union(CountryPopulation,CountryName); Using where +SELECT * FROM City +WHERE Country='USA' AND +(Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%'); +ID Name Country Population +3932 Paterson USA 149222 +3943 Pasadena USA 141674 +3953 Pasadena USA 133936 +3967 Paradise USA 124682 +3986 Palmdale USA 116670 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City +WHERE Country='USA' AND +(Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%'); +ID Name Country Population +3932 Paterson USA 149222 +3943 Pasadena USA 141674 +3953 Pasadena USA 133936 +3967 Paradise USA 124682 +3986 Palmdale USA 116670 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 DROP DATABASE world; use test; CREATE TABLE t1 ( diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result index 8250c91097e..0dfd5ef0883 100644 --- a/mysql-test/r/range_vs_index_merge_innodb.result +++ b/mysql-test/r/range_vs_index_merge_innodb.result @@ -1077,6 +1077,68 @@ ID BETWEEN 3500 AND 3800) AND Country='USA' AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300); ID Name Country Population 3798 Phoenix USA 1321045 +DROP INDEX Population ON City; +DROP INDEX Name ON City; +EXPLAIN +SELECT * FROM City +WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR +Country='USA' AND Name LIKE 'Pa%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge Country,CountryPopulation,CountryName CountryPopulation,CountryName 7,38 NULL 8 Using sort_union(CountryPopulation,CountryName); Using where +SELECT * FROM City USE INDEX() +WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR +Country='USA' AND Name LIKE 'Pa%'; +ID Name Country Population +3932 Paterson USA 149222 +3943 Pasadena USA 141674 +3953 Pasadena USA 133936 +3967 Paradise USA 124682 +3986 Palmdale USA 116670 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City +WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR +Country='USA' AND Name LIKE 'Pa%'; +ID Name Country Population +3932 Paterson USA 149222 +3943 Pasadena USA 141674 +3953 Pasadena USA 133936 +3967 Paradise USA 124682 +3986 Palmdale USA 116670 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +EXPLAIN +SELECT * FROM City +WHERE Country='USA' AND +(Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City index_merge Country,CountryPopulation,CountryName CountryPopulation,CountryName 7,38 NULL 8 Using sort_union(CountryPopulation,CountryName); Using where +SELECT * FROM City +WHERE Country='USA' AND +(Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%'); +ID Name Country Population +3932 Paterson USA 149222 +3943 Pasadena USA 141674 +3953 Pasadena USA 133936 +3967 Paradise USA 124682 +3986 Palmdale USA 116670 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 +SELECT * FROM City +WHERE Country='USA' AND +(Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%'); +ID Name Country Population +3932 Paterson USA 149222 +3943 Pasadena USA 141674 +3953 Pasadena USA 133936 +3967 Paradise USA 124682 +3986 Palmdale USA 116670 +4030 Sandy USA 101853 +4031 Athens-Clarke County USA 101489 +4032 Cambridge USA 101355 DROP DATABASE world; use test; CREATE TABLE t1 ( diff --git a/mysql-test/t/range_vs_index_merge.test b/mysql-test/t/range_vs_index_merge.test index 3e4614202b3..aa5f4620ffe 100755 --- a/mysql-test/t/range_vs_index_merge.test +++ b/mysql-test/t/range_vs_index_merge.test @@ -570,6 +570,51 @@ SELECT * FROM City AND (Name LIKE 'Pho%' OR ID BETWEEN 4000 AND 4300); +DROP INDEX Population ON City; +DROP INDEX Name ON City; + +# The pattern of the WHERE condition used in the following query is +# (key1|2_p1=c AND range(key1_p2)) OR (key1|2_p1=c AND range(key2_p2)) +# We get an index merge retrieval over key1, key2 for it + +EXPLAIN +SELECT * FROM City + WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR + Country='USA' AND Name LIKE 'Pa%'; + +# The following 2 queries check that the plans +# for the previous plan is valid + +SELECT * FROM City USE INDEX() + WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR + Country='USA' AND Name LIKE 'Pa%'; + +SELECT * FROM City + WHERE Country='USA' AND Population BETWEEN 101000 AND 102000 OR + Country='USA' AND Name LIKE 'Pa%'; + + +# The pattern of the WHERE condition used in the following query is +# key1|2_p1=c AND (range(key1_p2) OR range(key2_p2)) +# We get an index merge retrieval over key1, key2 for it + +EXPLAIN +SELECT * FROM City + WHERE Country='USA' AND + (Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%'); + +# The following 2 queries check that the plans +# for the previous plan is valid + +SELECT * FROM City + WHERE Country='USA' AND + (Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%'); + +SELECT * FROM City + WHERE Country='USA' AND + (Population BETWEEN 101000 AND 102000 OR Name LIKE 'Pa%'); + + DROP DATABASE world; use test; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 082bacc4810..65bef3bd38f 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -261,6 +261,11 @@ public: uint8 min_flag,max_flag,maybe_flag; uint8 part; // Which key part uint8 maybe_null; + /* + The ordinal number the least significant component encountered the ranges + of the SEL_ARG tree (the first component has number 1) + */ + uint max_part_no; /* Number of children of this element in the RB-tree, plus 1 for this element itself. @@ -737,12 +742,12 @@ public: uint real_keynr[MAX_KEY]; /* Number of SEL_ARG objects allocated by SEL_ARG::clone_tree operations */ uint alloced_sel_args; + KEY_PART *key[MAX_KEY]; /* First key parts of keys used in the query */ }; class PARAM : public RANGE_OPT_PARAM { public: - KEY_PART *key[MAX_KEY]; /* First key parts of keys used in the query */ ha_rows quick_rows[MAX_KEY]; longlong baseflag; uint max_key_part, range_count; @@ -2172,6 +2177,7 @@ SEL_ARG::SEL_ARG(SEL_ARG &arg) :Sql_alloc() min_value=arg.min_value; max_value=arg.max_value; next_key_part=arg.next_key_part; + max_part_no= arg.max_part_no; use_count=1; elements=1; } @@ -2189,7 +2195,7 @@ SEL_ARG::SEL_ARG(Field *f,const uchar *min_value_arg, :min_flag(0), max_flag(0), maybe_flag(0), maybe_null(f->real_maybe_null()), elements(1), use_count(1), field(f), min_value((uchar*) min_value_arg), max_value((uchar*) max_value_arg), next(0),prev(0), - next_key_part(0),color(BLACK),type(KEY_RANGE) + next_key_part(0), color(BLACK), type(KEY_RANGE), max_part_no(1) { left=right= &null_element; } @@ -2202,6 +2208,7 @@ SEL_ARG::SEL_ARG(Field *field_,uint8 part_, field(field_), min_value(min_value_), max_value(max_value_), next(0),prev(0),next_key_part(0),color(BLACK),type(KEY_RANGE) { + max_part_no= part+1; left=right= &null_element; } @@ -2244,6 +2251,7 @@ SEL_ARG *SEL_ARG::clone(RANGE_OPT_PARAM *param, SEL_ARG *new_parent, increment_use_count(1); tmp->color= color; tmp->elements= this->elements; + tmp->max_part_no= max_part_no; return tmp; } @@ -7000,14 +7008,14 @@ bool sel_trees_can_be_ored(RANGE_OPT_PARAM* param, ordable_keys bitmap of SEL_ARG trees that can be ored DESCRIPTION - For two trees tree1 and tree2 and the bitmap ordable_keys containing - bits for indexes that have SEL_ARG trees in range parts of both trees - and these SEL_ARG trees can be ored the function checks if there are - indexes for which SEL_ARG trees must be ored. Two SEL_ARG trees for the - same index must be ored if all indexes for which SEL_SRG trees from the - range parts of tree1 anf tree2 that can be ored have the same field as - their major index component. - + For two trees tree1 and tree2 the function checks whether they must be + ored. The function assumes that the bitmap ordable_keys contains bits for + those corresponding pairs of SEL_ARG trees from tree1 and tree2 that can + be ored. + We believe that tree1 and tree2 must be ored if any pair of SEL_ARG trees + r1 and r2, such that r1 is from tree1 and r2 is from tree2 and both + of them are marked in ordable_keys, can be merged. + NOTE The function sel_trees_must_be_ored as a rule is used in pair with the function sel_trees_can_be_ored. @@ -7031,21 +7039,31 @@ bool sel_trees_must_be_ored(RANGE_OPT_PARAM* param, if (!tmp.is_clear_all()) DBUG_RETURN(FALSE); - Field *field= 0; - uint part; - int key_no; - key_map::Iterator it(oredable_keys); - while ((key_no= it++) != key_map::Iterator::BITMAP_END) + int idx1, idx2; + key_map::Iterator it1(oredable_keys); + while ((idx1= it1++) != key_map::Iterator::BITMAP_END) { - SEL_ARG *key1= tree1->keys[key_no]; - if (!field) + KEY_PART *key1_init= param->key[idx1]+tree1->keys[idx1]->part; + KEY_PART *key1_end= param->key[idx1]+tree1->keys[idx1]->max_part_no; + key_map::Iterator it2(oredable_keys); + while ((idx2= it2++) != key_map::Iterator::BITMAP_END) { - field= key1->field; - part= key1->part; + if (idx2 <= idx1) + continue; + + KEY_PART *key2_init= param->key[idx2]+tree2->keys[idx2]->part; + KEY_PART *key2_end= param->key[idx2]+tree2->keys[idx2]->max_part_no; + KEY_PART *part1, *part2; + for (part1= key1_init, part2= key2_init; + part1 < key1_end && part2 < key2_end; + part1++, part2++) + { + if (!part1->field->eq(part2->field)) + DBUG_RETURN(FALSE); + } } - else if (!field->eq(key1->field)) - DBUG_RETURN(FALSE); } + DBUG_RETURN(TRUE); } @@ -7342,6 +7360,7 @@ and_all_keys(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, if (!key1) return &null_element; // Impossible ranges key1->use_count++; + key1->max_part_no= max(key2->max_part_no, key2->part+1); return key1; } @@ -7441,6 +7460,7 @@ key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint clone_flag) key1->use_count--; key2->use_count--; SEL_ARG *e1=key1->first(), *e2=key2->first(), *new_tree=0; + uint max_part_no= max(key1->max_part_no, key2->max_part_no); while (e1 && e2) { @@ -7478,6 +7498,7 @@ key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint clone_flag) key2->free_tree(); if (!new_tree) return &null_element; // Impossible range + new_tree->max_part_no= max_part_no; return new_tree; } @@ -7557,6 +7578,8 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2) bool key2_shared=key2->use_count != 0; key1->maybe_flag|=key2->maybe_flag; + uint max_part_no= max(key1->max_part_no, key2->max_part_no); + for (key2=key2->first(); key2; ) { SEL_ARG *tmp=key1->find_range(key2); // Find key1.min <= key2.min @@ -7749,6 +7772,7 @@ end: key2=next; } key1->use_count++; + key1->max_part_no= max_part_no; return key1; } From 914f33f2ca1070443583ab805f0094bd94951513 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 29 Oct 2009 17:36:35 -0700 Subject: [PATCH 04/33] Fixed a bug in the code of the patch for WL#24 that manifested itself when running the pbxt.group_min_max test leading to wrong result sets and execution plans for many test cases. When evaluating the index merge scans the code ignored the following: if an index merge contains a range tree, such that none of its SEL_ARG trees represents index ranges, then the index merge must be discarded as not usable for any index merge retrieval. --- sql/opt_range.cc | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 65bef3bd38f..8973bf30869 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -265,7 +265,7 @@ public: The ordinal number the least significant component encountered the ranges of the SEL_ARG tree (the first component has number 1) */ - uint max_part_no; + uint16 max_part_no; /* Number of children of this element in the RB-tree, plus 1 for this element itself. @@ -2195,9 +2195,10 @@ SEL_ARG::SEL_ARG(Field *f,const uchar *min_value_arg, :min_flag(0), max_flag(0), maybe_flag(0), maybe_null(f->real_maybe_null()), elements(1), use_count(1), field(f), min_value((uchar*) min_value_arg), max_value((uchar*) max_value_arg), next(0),prev(0), - next_key_part(0), color(BLACK), type(KEY_RANGE), max_part_no(1) + next_key_part(0), color(BLACK), type(KEY_RANGE) { left=right= &null_element; + max_part_no= 1; } SEL_ARG::SEL_ARG(Field *field_,uint8 part_, @@ -4247,18 +4248,16 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, /* In every tree of imerge remove SEL_ARG trees that do not make ranges. - Remove a tree from imerge if no SEL_ARG trees remain in it. + If after this removal some SEL_ARG tree becomes empty discard imerge. */ - SEL_TREE **new_trees_next= imerge->trees; - for (ptree= new_trees_next; ptree != imerge->trees_next; ptree++) + for (ptree= imerge->trees; ptree != imerge->trees_next; ptree++) { if (remove_nonrange_trees(param, *ptree)) - continue; - if (ptree > new_trees_next) - *new_trees_next= *ptree; - new_trees_next++; + { + imerge->trees_next= imerge->trees; + break; + } } - imerge->trees_next= new_trees_next; uint n_child_scans= imerge->trees_next - imerge->trees; @@ -7111,7 +7110,9 @@ bool sel_trees_must_be_ored(RANGE_OPT_PARAM* param, can be built. Such SEL_ARG trees should be removed from the range part before different range scans are evaluated. Such SEL_ARG trees also should be removed from all range trees of each index merge before different - possible index merge plans are evaluated. + possible index merge plans are evaluated. If after this removal one + of the range trees in the index merge becomes empty the whole index merge + must be discarded. RETURN 0 Ok, some suitable trees left From 617f3094dffeef7e12512541964d0915fbb5d3f9 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 31 Aug 2010 21:15:20 -0700 Subject: [PATCH 05/33] Adjusted results after merge --- mysql-test/r/range_vs_index_merge_innodb.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result index 0dfd5ef0883..dd97415b1dc 100644 --- a/mysql-test/r/range_vs_index_merge_innodb.result +++ b/mysql-test/r/range_vs_index_merge_innodb.result @@ -372,7 +372,7 @@ WHERE ((ID < 600) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 300 AND 600) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 1062 Using where +1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 1242 Using where SELECT * FROM City USE INDEX () WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND From 3a61fbe972f96a8eed3ed9d51c2c3594860bbc53 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 11 Sep 2010 12:18:58 -0700 Subject: [PATCH 06/33] WL#24: post review fixes. --- sql/opt_range.cc | 42 +++++++++++++++++++++--------------------- sql/sql_list.h | 3 --- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index b48b7fb8a08..12bbc335d48 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -262,8 +262,8 @@ public: uint8 part; // Which key part uint8 maybe_null; /* - The ordinal number the least significant component encountered the ranges - of the SEL_ARG tree (the first component has number 1) + The ordinal number the least significant component encountered in + the ranges of the SEL_ARG tree (the first component has number 1) */ uint16 max_part_no; /* @@ -851,8 +851,7 @@ static bool eq_tree(SEL_ARG* a,SEL_ARG *b); static SEL_ARG null_element(SEL_ARG::IMPOSSIBLE); static bool null_part_in_key(KEY_PART *key_part, const uchar *key, uint length); -static bool sel_trees_have_common_keys(RANGE_OPT_PARAM* param, - SEL_TREE *tree1, SEL_TREE *tree2, +static bool sel_trees_have_common_keys(SEL_TREE *tree1, SEL_TREE *tree2, key_map *common_keys); static void eliminate_single_tree_imerges(RANGE_OPT_PARAM *param, SEL_TREE *tree); @@ -964,7 +963,7 @@ bool SEL_IMERGE::have_common_keys(RANGE_OPT_PARAM *param, SEL_TREE *tree) or_tree != bound; or_tree++) { key_map common_keys; - if (sel_trees_have_common_keys(param, *or_tree, tree, &common_keys)) + if (sel_trees_have_common_keys(*or_tree, tree, &common_keys)) return TRUE; } return FALSE; @@ -988,12 +987,15 @@ bool SEL_IMERGE::have_common_keys(RANGE_OPT_PARAM *param, SEL_TREE *tree) If this imerge m represent the formula RT_1 OR ... OR RT_k then the resulting imerge of the function represents the formula - (RT_1 AND RT) OR ... (RT_k AND RT) + (RT_1 AND RT) OR ... OR (RT_k AND RT) The function calls the function and_range_trees to construct the range tree representing (RT_i AND RT). NOTE - The function may return an empty imerge without any range trees + The function may return an empty imerge without any range trees. + This happens when each call of and_range_trees returns an + impossible range tree (SEL_TREE::IMPOSSIBLE). + Example: (key1 < 2 AND key2 > 10) AND (key1 > 4 OR key2 < 6). RETURN 0 if the operation is a success @@ -1005,13 +1007,12 @@ int SEL_IMERGE::and_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree, { for (SEL_TREE** or_tree= trees; or_tree != trees_next; or_tree++) { - SEL_TREE *result= 0; - key_map result_keys; - if (!(result= new SEL_TREE())) + SEL_TREE *res_or_tree= 0; + if (!(res_or_tree= new SEL_TREE())) return (-1); - if (!and_range_trees(param, *or_tree, tree, result)) + if (!and_range_trees(param, *or_tree, tree, res_or_tree)) { - if (new_imerge->or_sel_tree(param, result)) + if (new_imerge->or_sel_tree(param, res_or_tree)) return (-1); } } @@ -1030,7 +1031,7 @@ int SEL_IMERGE::and_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree, is_last_check_pass OUT <=> no more calls of the function for this imerge DESCRIPTION - The functions performs OR operation on this imerge m and the range part + The function performs OR operation on this imerge m and the range part of the SEL_TREE tree rt. It always replaces this imerge with the result of the operation. @@ -1044,7 +1045,7 @@ int SEL_IMERGE::and_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree, 1. In the first mode, when is_first_check_pass==TRUE : 1.1. If rt must be ored(see the function sel_trees_must_be_ored) with some rt_j (there may be only one such range tree in the imerge) - then the function produces the imerge representing the formula + then the function produces an imerge representing the formula RT_1 OR ... OR (RT_j OR RT) OR ... OR RT_k, where the tree for (RT_j OR RT) is built by oring the pairs of SEL_ARG trees for the corresponding indexes @@ -1090,7 +1091,8 @@ int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param, { bool must_be_ored= sel_trees_must_be_ored(param, *or_tree, tree, ored_keys); - if (must_be_ored == is_first_check_pass) { + if (must_be_ored == is_first_check_pass) + { result_keys.clear_all(); result= *or_tree; for (uint key_no= 0; key_no < param->keys; key_no++) @@ -6962,7 +6964,6 @@ void eliminate_single_tree_imerges(RANGE_OPT_PARAM *param, SEL_TREE *tree) SYNOPSIS sel_trees_have_common_keys() - param Context info for the function tree1 SEL_TREE for the first tree tree2 SEL_TREE for the second tree common_keys OUT bitmap of all indexes with ranges in both trees @@ -6979,8 +6980,7 @@ void eliminate_single_tree_imerges(RANGE_OPT_PARAM *param, SEL_TREE *tree) */ static -bool sel_trees_have_common_keys(RANGE_OPT_PARAM* param, - SEL_TREE *tree1, SEL_TREE *tree2, +bool sel_trees_have_common_keys(SEL_TREE *tree1, SEL_TREE *tree2, key_map *common_keys) { *common_keys= tree1->keys_map; @@ -7027,7 +7027,7 @@ bool sel_trees_can_be_ored(RANGE_OPT_PARAM* param, key_map *common_keys) { DBUG_ENTER("sel_trees_can_be_ored"); - if (!sel_trees_have_common_keys(param, tree1, tree2, common_keys)) + if (!sel_trees_have_common_keys(tree1, tree2, common_keys)) DBUG_RETURN(FALSE); int key_no; key_map::Iterator it(*common_keys); @@ -7151,7 +7151,7 @@ bool sel_trees_must_be_ored(RANGE_OPT_PARAM* param, key1part1=1 AND key2part1=3 OR key2part1=3 AND key2part2=2 for which an index merge can be built. - Any final SEL_TREE may contains SEL_ARG trees for which no quick select + Any final SEL_TREE may contain SEL_ARG trees for which no quick select can be built. Such SEL_ARG trees should be removed from the range part before different range scans are evaluated. Such SEL_ARG trees also should be removed from all range trees of each index merge before different @@ -7335,7 +7335,7 @@ tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2) result->merges.push_back(imerge_from_ranges) || imerge_from_ranges->or_sel_tree(param, rt1) || imerge_from_ranges->or_sel_tree(param, rt2)) - result= NULL; + result= NULL; } if (!result) DBUG_RETURN(result); diff --git a/sql/sql_list.h b/sql/sql_list.h index 6a568c2dfd7..69798079a0f 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -235,14 +235,11 @@ public: { if (!list->is_empty()) { -#if 0 -#else if (is_empty()) { *this= *list; return; } -#endif *last= list->first; last= list->last; elements+= list->elements; From 69dd773b67a9892561f148964e51d3be606f7c77 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 13 Sep 2010 15:22:11 -0700 Subject: [PATCH 07/33] An implementation of index intersect via a modified Unique class. This code is planned to be used for mwl#21. --- include/my_tree.h | 1 + mysys/tree.c | 2 + sql/filesort.cc | 113 +++++++++---- sql/opt_range.cc | 420 ++++++++++++++++++++++++++++++++++++++++++---- sql/opt_range.h | 61 ++++++- sql/sql_class.h | 14 +- sql/sql_select.cc | 6 +- sql/sql_sort.h | 6 + sql/uniques.cc | 51 +++++- 9 files changed, 598 insertions(+), 76 deletions(-) diff --git a/include/my_tree.h b/include/my_tree.h index ceeb849ad0c..ca207932c73 100644 --- a/include/my_tree.h +++ b/include/my_tree.h @@ -31,6 +31,7 @@ extern "C" { #define tree_set_pointer(element,ptr) *((uchar **) (element+1))=((uchar*) (ptr)) #define TREE_NO_DUPS 1 +#define TREE_ONLY_DUPS 2 typedef enum { left_root_right, right_root_left } TREE_WALK; typedef uint32 element_count; diff --git a/mysys/tree.c b/mysys/tree.c index e4854581204..70f2972b03f 100644 --- a/mysys/tree.c +++ b/mysys/tree.c @@ -221,6 +221,8 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size, } if (element == &tree->null_element) { + if (tree->flag & TREE_ONLY_DUPS) + return((TREE_ELEMENT *) 1); uint alloc_size=sizeof(TREE_ELEMENT)+key_size+tree->size_of_element; tree->allocated+=alloc_size; diff --git a/sql/filesort.cc b/sql/filesort.cc index 0e476d3d957..2bc1a694126 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -50,10 +50,6 @@ static int write_keys(SORTPARAM *param,uchar * *sort_keys, uint count, IO_CACHE *buffer_file, IO_CACHE *tempfile); static void make_sortkey(SORTPARAM *param,uchar *to, uchar *ref_pos); static void register_used_fields(SORTPARAM *param); -static int merge_index(SORTPARAM *param,uchar *sort_buffer, - BUFFPEK *buffpek, - uint maxbuffer,IO_CACHE *tempfile, - IO_CACHE *outfile); static bool save_index(SORTPARAM *param,uchar **sort_keys, uint count, FILESORT_INFO *table_sort); static uint suffix_length(ulong string_length); @@ -145,6 +141,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, /* filesort cannot handle zero-length records. */ DBUG_ASSERT(param.sort_length); param.ref_length= table->file->ref_length; + param.min_dupl_count= 0; param.addon_field= 0; param.addon_length= 0; if (!(table->file->ha_table_flags() & HA_FAST_KEY_READ) && @@ -1216,7 +1213,13 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, rec_length= param->rec_length; res_length= param->res_length; sort_length= param->sort_length; - offset= rec_length-res_length; + element_count dupl_count; + uchar *src; + uint dupl_count_ofs= rec_length-sizeof(element_count); + uint min_dupl_count= param->min_dupl_count; + offset= rec_length- + (flag && min_dupl_count ? sizeof(dupl_count) : 0)-res_length; + uint wr_len= flag ? res_length : rec_length; maxcount= (ulong) (param->keys/((uint) (Tb-Fb) +1)); to_start_filepos= my_b_tell(to_file); strpos= sort_buffer; @@ -1262,16 +1265,20 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, */ buffpek= (BUFFPEK*) queue_top(&queue); memcpy(param->unique_buff, buffpek->key, rec_length); - if (my_b_write(to_file, (uchar*) buffpek->key, rec_length)) - { - error=1; goto err; /* purecov: inspected */ - } + if (min_dupl_count) + memcpy(&dupl_count, param->unique_buff+dupl_count_ofs, + sizeof(dupl_count)); buffpek->key+= rec_length; - buffpek->mem_count--; - if (!--max_rows) + if (! --buffpek->mem_count) { - error= 0; /* purecov: inspected */ - goto end; /* purecov: inspected */ + if (!(error= (int) read_to_buffer(from_file,buffpek, + rec_length))) + { + VOID(queue_remove(&queue,0)); + reuse_freed_buff(&queue, buffpek, rec_length); + } + else if (error == -1) + goto err; /* purecov: inspected */ } queue_replaced(&queue); // Top element has been used } @@ -1287,26 +1294,41 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, for (;;) { buffpek= (BUFFPEK*) queue_top(&queue); + src= buffpek->key; if (cmp) // Remove duplicates { if (!(*cmp)(first_cmp_arg, &(param->unique_buff), (uchar**) &buffpek->key)) - goto skip_duplicate; - memcpy(param->unique_buff, (uchar*) buffpek->key, rec_length); + { + if (min_dupl_count) + { + element_count cnt; + memcpy(&cnt, (uchar *) buffpek->key+dupl_count_ofs, sizeof(cnt)); + dupl_count+= cnt; + } + goto skip_duplicate; + } + if (min_dupl_count) + { + memcpy(param->unique_buff+dupl_count_ofs, &dupl_count, + sizeof(dupl_count)); + } + src= param->unique_buff; } - if (flag == 0) + + if (!flag || !min_dupl_count || dupl_count >= min_dupl_count) { - if (my_b_write(to_file,(uchar*) buffpek->key, rec_length)) + if (my_b_write(to_file, src+(flag ? offset : 0), wr_len)) { error=1; goto err; /* purecov: inspected */ } } - else - { - if (my_b_write(to_file, (uchar*) buffpek->key+offset, res_length)) - { - error=1; goto err; /* purecov: inspected */ - } + if (cmp) + { + memcpy(param->unique_buff, (uchar*) buffpek->key, rec_length); + if (min_dupl_count) + memcpy(&dupl_count, param->unique_buff+dupl_count_ofs, + sizeof(dupl_count)); } if (!--max_rows) { @@ -1343,9 +1365,33 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, { if (!(*cmp)(first_cmp_arg, &(param->unique_buff), (uchar**) &buffpek->key)) { - buffpek->key+= rec_length; // Remove duplicate + if (min_dupl_count) + { + element_count cnt; + memcpy(&cnt, (uchar *) buffpek->key+dupl_count_ofs, sizeof(cnt)); + dupl_count+= cnt; + } + buffpek->key+= rec_length; --buffpek->mem_count; } + + if (min_dupl_count) + memcpy(param->unique_buff+dupl_count_ofs, &dupl_count, + sizeof(dupl_count)); + + if (!flag || !min_dupl_count || dupl_count >= min_dupl_count) + { + src= param->unique_buff; + if (my_b_write(to_file, src+(flag ? offset : 0), wr_len)) + { + error=1; goto err; /* purecov: inspected */ + } + if (!--max_rows) + { + error= 0; + goto end; + } + } } do @@ -1367,12 +1413,17 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, else { register uchar *end; - strpos= buffpek->key+offset; - for (end= strpos+buffpek->mem_count*rec_length ; - strpos != end ; - strpos+= rec_length) - { - if (my_b_write(to_file, strpos, res_length)) + src= buffpek->key+offset; + for (end= src+buffpek->mem_count*rec_length ; + src != end ; + src+= rec_length) + { + if (flag && min_dupl_count && + memcmp(&min_dupl_count, src+dupl_count_ofs, + sizeof(dupl_count_ofs))<0) + continue; + + if (my_b_write(to_file, src, wr_len)) { error=1; goto err; } @@ -1393,7 +1444,7 @@ err: /* Do a merge to output-file (save only positions) */ -static int merge_index(SORTPARAM *param, uchar *sort_buffer, +int merge_index(SORTPARAM *param, uchar *sort_buffer, BUFFPEK *buffpek, uint maxbuffer, IO_CACHE *tempfile, IO_CACHE *outfile) { diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 9fac099855e..f868be5f6b9 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -697,6 +697,9 @@ public: key_map ror_scans_map; /* bitmask of ROR scan-able elements in keys */ uint n_ror_scans; /* number of set bits in ror_scans_map */ + struct st_index_scan_info **index_scans; /* list of index scans */ + struct st_index_scan_info **index_scans_end; /* last index scan */ + struct st_ror_scan_info **ror_scans; /* list of ROR key scans */ struct st_ror_scan_info **ror_scans_end; /* last ROR scan */ /* Note that #records for each key scan is stored in table->quick_rows */ @@ -776,9 +779,11 @@ class TABLE_READ_PLAN; class TRP_RANGE; class TRP_ROR_INTERSECT; class TRP_ROR_UNION; + class TRP_INDEX_INTERSECT; class TRP_INDEX_MERGE; class TRP_GROUP_MIN_MAX; +struct st_index_scan_info; struct st_ror_scan_info; static SEL_TREE * get_mm_parts(RANGE_OPT_PARAM *param,COND *cond_func,Field *field, @@ -804,6 +809,9 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, bool update_tbl_stats, double read_time); static +TRP_INDEX_INTERSECT *get_best_index_intersect(PARAM *param, SEL_TREE *tree, + double read_time); +static TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, double read_time, bool *are_all_covering); @@ -1742,7 +1750,7 @@ int QUICK_INDEX_MERGE_SELECT::init() int QUICK_INDEX_MERGE_SELECT::reset() { DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::reset"); - DBUG_RETURN(read_keys_and_merge()); + DBUG_RETURN (read_keys_and_merge()); } bool @@ -1778,6 +1786,64 @@ QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT() DBUG_VOID_RETURN; } +QUICK_INDEX_INTERSECT_SELECT::QUICK_INDEX_INTERSECT_SELECT(THD *thd_param, + TABLE *table) + :pk_quick_select(NULL), thd(thd_param) +{ + DBUG_ENTER("QUICK_INDEX_INTERSECT_SELECT::QUICK_INDEX_INTERSECT_SELECT"); + index= MAX_KEY; + head= table; + bzero(&read_record, sizeof(read_record)); + init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0); + DBUG_VOID_RETURN; +} + +int QUICK_INDEX_INTERSECT_SELECT::init() +{ + DBUG_ENTER("QUICK_INDEX_INTERSECT_SELECT::init"); + DBUG_RETURN(0); +} + +int QUICK_INDEX_INTERSECT_SELECT::reset() +{ + DBUG_ENTER("QUICK_INDEX_INTERSECT_SELECT::reset"); + DBUG_RETURN (read_keys_and_merge()); +} + +bool +QUICK_INDEX_INTERSECT_SELECT::push_quick_back(QUICK_RANGE_SELECT *quick_sel_range) +{ + /* + Save quick_select that does scan on clustered primary key as it will be + processed separately. + */ + if (head->file->primary_key_is_clustered() && + quick_sel_range->index == head->s->primary_key) + pk_quick_select= quick_sel_range; + else + return quick_selects.push_back(quick_sel_range); + return 0; +} + +QUICK_INDEX_INTERSECT_SELECT::~QUICK_INDEX_INTERSECT_SELECT() +{ + List_iterator_fast quick_it(quick_selects); + QUICK_RANGE_SELECT* quick; + DBUG_ENTER("QUICK_INDEX_INTERSECT_SELECT::~QUICK_INDEX_INTERSECT_SELECT"); + delete unique; + quick_it.rewind(); + while ((quick= quick_it++)) + quick->file= NULL; + quick_selects.delete_elements(); + delete pk_quick_select; + /* It's ok to call the next two even if they are already deinitialized */ + end_read_record(&read_record); + free_io_cache(head); + free_root(&alloc,MYF(0)); + DBUG_VOID_RETURN; +} + + QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(THD *thd_param, TABLE *table, @@ -2558,6 +2624,24 @@ public: }; +/* + Plan for QUICK_INDEX_INTERSECT_SELECT scan. + QUICK_INDEX_INTERSECT_SELECT always retrieves full rows, so retrieve_full_rows + is ignored by make_quick. +*/ + +class TRP_INDEX_INTERSECT : public TABLE_READ_PLAN +{ +public: + TRP_INDEX_INTERSECT() {} /* Remove gcc warning */ + virtual ~TRP_INDEX_INTERSECT() {} /* Remove gcc warning */ + QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows, + MEM_ROOT *parent_alloc); + TRP_RANGE **range_scans; /* array of ptrs to plans of merged scans */ + TRP_RANGE **range_scans_end; /* end of the array */ +}; + + /* Plan for QUICK_INDEX_MERGE_SELECT scan. QUICK_ROR_INTERSECT_SELECT always retrieves full rows, so retrieve_full_rows @@ -2625,6 +2709,30 @@ public: }; +typedef struct st_index_scan_info +{ + uint idx; /* # of used key in param->keys */ + uint keynr; /* # of used key in table */ + uint range_count; + ha_rows records; /* estimate of # records this scan will return */ + + /* Set of intervals over key fields that will be used for row retrieval. */ + SEL_ARG *sel_arg; + + /* Fields used in the query and covered by this ROR scan. */ + MY_BITMAP covered_fields; + uint used_fields_covered; /* # of set bits in covered_fields */ + int key_rec_length; /* length of key record (including rowid) */ + + /* + Cost of reading all index records with values in sel_arg intervals set + (assuming there is no need to access full table records) + */ + double index_read_cost; + uint first_uncovered_field; /* first unused bit in covered_fields */ + uint key_components; /* # of parts in the key */ +} INDEX_SCAN_INFO; + /* Fill param->needed_fields with bitmap of fields used in the query. SYNOPSIS @@ -2903,6 +3011,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, */ TRP_RANGE *range_trp; TRP_ROR_INTERSECT *rori_trp; + TRP_INDEX_INTERSECT *intersect_trp; bool can_build_covering= FALSE; remove_nonrange_trees(¶m, tree); @@ -2942,6 +3051,18 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, best_trp= rori_trp; } } +#if 1 +#else + if (optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE)) + { + if ((intersect_trp= get_best_index_intersect(¶m, tree, + best_read_time))) + { + best_trp= intersect_trp; + best_read_time= best_trp->read_cost; + } + } +#endif if (optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE)) { @@ -4605,6 +4726,85 @@ TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge, DBUG_RETURN(trp); } +static +TRP_INDEX_INTERSECT *get_best_index_intersect(PARAM *param, SEL_TREE *tree, + double read_time) +{ + uint i; + uint unique_calc_buff_size; + TRP_RANGE **cur_range; + TRP_RANGE **range_scans; + TRP_INDEX_INTERSECT *intersect_trp= NULL; + double intersect_cost= 0.0; + ha_rows scan_records= 0; + double selectivity= 1.0; + ha_rows table_records= param->table->file->stats.records; + uint n_index_scans= tree->index_scans_end - tree->index_scans; + + DBUG_ENTER("get_best_index_intersect"); + + if (!n_index_scans) + DBUG_RETURN(NULL); + + if (!(range_scans= (TRP_RANGE**)alloc_root(param->mem_root, + sizeof(TRP_RANGE *)* + n_index_scans))) + DBUG_RETURN(NULL); + + for (i= 0, cur_range= range_scans; i < n_index_scans; i++) + { + struct st_index_scan_info *index_scan= tree->index_scans[i]; + if ((*cur_range= new (param->mem_root) TRP_RANGE(index_scan->sel_arg, + index_scan->idx))) + { + TRP_RANGE *trp= *cur_range; + trp->records= index_scan->records; + trp->is_ror= FALSE; + trp->read_cost= get_index_only_read_time(param, index_scan->records, + index_scan->keynr); + scan_records+= trp->records; + selectivity*= (double) trp->records/table_records; + intersect_cost+= trp->read_cost; + cur_range++; + } + } + + /* Add Unique operations cost */ + unique_calc_buff_size= + Unique::get_cost_calc_buff_size((ulong)scan_records, + param->table->file->ref_length, + param->thd->variables.sortbuff_size); + if (param->imerge_cost_buff_size < unique_calc_buff_size) + { + if (!(param->imerge_cost_buff= (uint*)alloc_root(param->mem_root, + unique_calc_buff_size))) + DBUG_RETURN(NULL); + param->imerge_cost_buff_size= unique_calc_buff_size; + } + + intersect_cost += + Unique::get_use_cost(param->imerge_cost_buff, scan_records, + param->table->file->ref_length, + param->thd->variables.sortbuff_size); + + intersect_cost += get_sweep_read_cost(param, + (ha_rows) (table_records*selectivity)); + + if (intersect_cost < read_time) + { + if ((intersect_trp= new (param->mem_root)TRP_INDEX_INTERSECT)) + { + intersect_trp->read_cost= intersect_cost; + intersect_trp->records= (ha_rows) table_records*selectivity; + set_if_bigger(intersect_trp->records, 1); + intersect_trp->range_scans= range_scans; + intersect_trp->range_scans_end= cur_range; + read_time= intersect_cost; + } + } + DBUG_RETURN(intersect_trp); +} + /* Calculate cost of 'index only' scan for given index and number of records. @@ -4642,27 +4842,8 @@ static double get_index_only_read_time(const PARAM* param, ha_rows records, } -typedef struct st_ror_scan_info -{ - uint idx; /* # of used key in param->keys */ - uint keynr; /* # of used key in table */ - ha_rows records; /* estimate of # records this scan will return */ - - /* Set of intervals over key fields that will be used for row retrieval. */ - SEL_ARG *sel_arg; - - /* Fields used in the query and covered by this ROR scan. */ - MY_BITMAP covered_fields; - uint used_fields_covered; /* # of set bits in covered_fields */ - int key_rec_length; /* length of key record (including rowid) */ - - /* - Cost of reading all index records with values in sel_arg intervals set - (assuming there is no need to access full table records) - */ - double index_read_cost; - uint first_uncovered_field; /* first unused bit in covered_fields */ - uint key_components; /* # of parts in the key */ +typedef struct st_ror_scan_info : INDEX_SCAN_INFO +{ } ROR_SCAN_INFO; @@ -5521,6 +5702,14 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, "tree scans");); tree->ror_scans_map.clear_all(); tree->n_ror_scans= 0; + tree->index_scans= 0; + if (!tree->keys_map.is_clear_all()) + { + tree->index_scans= + (INDEX_SCAN_INFO **) alloc_root(param->mem_root, + sizeof(INDEX_SCAN_INFO *) * param->keys); + } + tree->index_scans_end= tree->index_scans; for (idx= 0,key=tree->keys, end=key+param->keys; key != end ; key++,idx++) @@ -5529,6 +5718,7 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, double found_read_time; if (*key) { + INDEX_SCAN_INFO *index_scan; uint keynr= param->real_keynr[idx]; if ((*key)->type == SEL_ARG::MAYBE_KEY || (*key)->maybe_flag) @@ -5538,6 +5728,17 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, (bool) param->table->covering_keys.is_set(keynr); found_records= check_quick_select(param, idx, *key, update_tbl_stats); + if (found_records != HA_POS_ERROR && tree->index_scans && + (index_scan= (INDEX_SCAN_INFO *)alloc_root(param->mem_root, + sizeof(INDEX_SCAN_INFO)))) + { + index_scan->idx= idx; + index_scan->keynr= keynr; + index_scan->range_count= param->range_count; + index_scan->records= found_records; + index_scan->sel_arg= *key; + *tree->index_scans_end++= index_scan; + } if (param->is_ror_scan) { tree->n_ror_scans++; @@ -5632,6 +5833,34 @@ QUICK_SELECT_I *TRP_INDEX_MERGE::make_quick(PARAM *param, return quick_imerge; } +QUICK_SELECT_I *TRP_INDEX_INTERSECT::make_quick(PARAM *param, + bool retrieve_full_rows, + MEM_ROOT *parent_alloc) +{ + QUICK_INDEX_INTERSECT_SELECT *quick_intersect; + QUICK_RANGE_SELECT *quick; + /* index_merge always retrieves full rows, ignore retrieve_full_rows */ + if (!(quick_intersect= new QUICK_INDEX_INTERSECT_SELECT(param->thd, param->table))) + return NULL; + + quick_intersect->records= records; + quick_intersect->read_time= read_cost; + for (TRP_RANGE **range_scan= range_scans; range_scan != range_scans_end; + range_scan++) + { + if (!(quick= (QUICK_RANGE_SELECT*) + ((*range_scan)->make_quick(param, FALSE, &quick_intersect->alloc)))|| + quick_intersect->push_quick_back(quick)) + { + delete quick; + delete quick_intersect; + return NULL; + } + } + return quick_intersect; +} + + QUICK_SELECT_I *TRP_ROR_INTERSECT::make_quick(PARAM *param, bool retrieve_full_rows, MEM_ROOT *parent_alloc) @@ -9025,6 +9254,18 @@ bool QUICK_INDEX_MERGE_SELECT::is_keys_used(const MY_BITMAP *fields) return 0; } +bool QUICK_INDEX_INTERSECT_SELECT::is_keys_used(const MY_BITMAP *fields) +{ + QUICK_RANGE_SELECT *quick; + List_iterator_fast it(quick_selects); + while ((quick= it++)) + { + if (is_key_used(head, quick->index, fields)) + return 1; + } + return 0; +} + bool QUICK_ROR_INTERSECT_SELECT::is_keys_used(const MY_BITMAP *fields) { QUICK_RANGE_SELECT *quick; @@ -9170,13 +9411,20 @@ err: other error */ -int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() +int read_keys_and_merge_scans(THD *thd, + TABLE *head, + List quick_selects, + QUICK_RANGE_SELECT *pk_quick_select, + READ_RECORD *read_record, + bool intersection, + Unique **unique_ptr) { List_iterator_fast cur_quick_it(quick_selects); QUICK_RANGE_SELECT* cur_quick; int result; + Unique *unique= *unique_ptr; handler *file= head->file; - DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::read_keys_and_merge"); + DBUG_ENTER("read_keys_and_merge"); /* We're going to just read rowids. */ if (!head->key_read) @@ -9187,6 +9435,7 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() cur_quick_it.rewind(); cur_quick= cur_quick_it++; + bool first_quick= TRUE; DBUG_ASSERT(cur_quick != 0); /* @@ -9204,9 +9453,11 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() unique= new Unique(refpos_order_cmp, (void *)file, file->ref_length, - thd->variables.sortbuff_size); + thd->variables.sortbuff_size, + intersection ? quick_selects.elements : 0); if (!unique) goto err; + *unique_ptr= unique; } else unique->reset(); @@ -9218,6 +9469,12 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() { while ((result= cur_quick->get_next()) == HA_ERR_END_OF_FILE) { + if (first_quick) + { + first_quick= FALSE; + if (intersection && unique->is_in_memory()) + unique->close_for_expansion(); + } cur_quick->range_end(); cur_quick= cur_quick_it++; if (!cur_quick) @@ -9257,12 +9514,11 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() sequence. */ result= unique->get(head); - doing_pk_scan= FALSE; /* index_merge currently doesn't support "using index" at all */ head->disable_keyread(); - init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE); + init_read_record(read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE); DBUG_RETURN(result); err: @@ -9271,6 +9527,17 @@ err: } +int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() + +{ + int result; + DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::read_keys_and_merge"); + result= read_keys_and_merge_scans(thd, head, quick_selects, pk_quick_select, + &read_record, FALSE, &unique); + doing_pk_scan= FALSE; + DBUG_RETURN(result); +} + /* Get next row for index_merge. NOTES @@ -9307,6 +9574,44 @@ int QUICK_INDEX_MERGE_SELECT::get_next() DBUG_RETURN(result); } +int QUICK_INDEX_INTERSECT_SELECT::read_keys_and_merge() + +{ + int result; + DBUG_ENTER("QUICK_INDEX_INTERSECT_SELECT::read_keys_and_merge"); + result= read_keys_and_merge_scans(thd, head, quick_selects, pk_quick_select, + &read_record, TRUE, &unique); + doing_pk_scan= FALSE; + DBUG_RETURN(result); +} + +int QUICK_INDEX_INTERSECT_SELECT::get_next() +{ + int result; + DBUG_ENTER("QUICK_INDEX_INTERSECT_SELECT::get_next"); + + if (doing_pk_scan) + DBUG_RETURN(pk_quick_select->get_next()); + + if ((result= read_record.read_record(&read_record)) == -1) + { + result= HA_ERR_END_OF_FILE; + end_read_record(&read_record); + free_io_cache(head); + /* All rows from Unique have been retrieved, do a clustered PK scan */ + if (pk_quick_select) + { + doing_pk_scan= TRUE; + if ((result= pk_quick_select->init()) || + (result= pk_quick_select->reset())) + DBUG_RETURN(result); + DBUG_RETURN(pk_quick_select->get_next()); + } + } + + DBUG_RETURN(result); +} + /* Retrieve next record. @@ -10010,6 +10315,28 @@ void QUICK_INDEX_MERGE_SELECT::add_info_string(String *str) str->append(')'); } +void QUICK_INDEX_INTERSECT_SELECT::add_info_string(String *str) +{ + QUICK_RANGE_SELECT *quick; + bool first= TRUE; + List_iterator_fast it(quick_selects); + str->append(STRING_WITH_LEN("sort_intersect(")); + while ((quick= it++)) + { + if (!first) + str->append(','); + else + first= FALSE; + quick->add_info_string(str); + } + if (pk_quick_select) + { + str->append(','); + pk_quick_select->add_info_string(str); + } + str->append(')'); +} + void QUICK_ROR_INTERSECT_SELECT::add_info_string(String *str) { bool first= TRUE; @@ -10034,6 +10361,7 @@ void QUICK_ROR_INTERSECT_SELECT::add_info_string(String *str) str->append(')'); } + void QUICK_ROR_UNION_SELECT::add_info_string(String *str) { bool first= TRUE; @@ -10063,8 +10391,12 @@ void QUICK_RANGE_SELECT::add_keys_and_lengths(String *key_names, used_lengths->append(buf, length); } -void QUICK_INDEX_MERGE_SELECT::add_keys_and_lengths(String *key_names, - String *used_lengths) +static +void add_keys_and_lengths_of_index_scans(TABLE *head, + List quick_selects, + QUICK_RANGE_SELECT *pk_quick_select, + String *key_names, + String *used_lengths) { char buf[64]; uint length; @@ -10098,6 +10430,20 @@ void QUICK_INDEX_MERGE_SELECT::add_keys_and_lengths(String *key_names, } } +void QUICK_INDEX_MERGE_SELECT::add_keys_and_lengths(String *key_names, + String *used_lengths) +{ + add_keys_and_lengths_of_index_scans(head, quick_selects, pk_quick_select, + key_names, used_lengths); +} + +void QUICK_INDEX_INTERSECT_SELECT::add_keys_and_lengths(String *key_names, + String *used_lengths) +{ + add_keys_and_lengths_of_index_scans(head, quick_selects, pk_quick_select, + key_names, used_lengths); +} + void QUICK_ROR_INTERSECT_SELECT::add_keys_and_lengths(String *key_names, String *used_lengths) { @@ -12469,6 +12815,22 @@ void QUICK_INDEX_MERGE_SELECT::dbug_dump(int indent, bool verbose) fprintf(DBUG_FILE, "%*s}\n", indent, ""); } +void QUICK_INDEX_INTERSECT_SELECT::dbug_dump(int indent, bool verbose) +{ + List_iterator_fast it(quick_selects); + QUICK_RANGE_SELECT *quick; + fprintf(DBUG_FILE, "%*squick index_intersect select\n", indent, ""); + fprintf(DBUG_FILE, "%*smerged scans {\n", indent, ""); + while ((quick= it++)) + quick->dbug_dump(indent+2, verbose); + if (pk_quick_select) + { + fprintf(DBUG_FILE, "%*sclustered PK quick:\n", indent, ""); + pk_quick_select->dbug_dump(indent+2, verbose); + } + fprintf(DBUG_FILE, "%*s}\n", indent, ""); +} + void QUICK_ROR_INTERSECT_SELECT::dbug_dump(int indent, bool verbose) { List_iterator_fast it(quick_selects); diff --git a/sql/opt_range.h b/sql/opt_range.h index f2a1cce29b5..0be082e4c9a 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -274,12 +274,13 @@ public: enum { QS_TYPE_RANGE = 0, - QS_TYPE_INDEX_MERGE = 1, - QS_TYPE_RANGE_DESC = 2, - QS_TYPE_FULLTEXT = 3, - QS_TYPE_ROR_INTERSECT = 4, - QS_TYPE_ROR_UNION = 5, - QS_TYPE_GROUP_MIN_MAX = 6 + QS_TYPE_INDEX_INTERSECT = 1, + QS_TYPE_INDEX_MERGE = 2, + QS_TYPE_RANGE_DESC = 3, + QS_TYPE_FULLTEXT = 4, + QS_TYPE_ROR_INTERSECT = 5, + QS_TYPE_ROR_UNION = 6, + QS_TYPE_GROUP_MIN_MAX = 7 }; /* Get type of this quick select - one of the QS_TYPE_* values */ @@ -393,8 +394,17 @@ protected: friend QUICK_RANGE_SELECT *get_quick_select(PARAM*,uint idx, SEL_ARG *key_tree, MEM_ROOT *alloc); + friend + int read_keys_and_merge_scans(THD *thd, TABLE *head, + List quick_selects, + QUICK_RANGE_SELECT *pk_quick_select, + READ_RECORD *read_record, + bool intersection, + Unique **unique_ptr); + friend class QUICK_SELECT_DESC; friend class QUICK_INDEX_MERGE_SELECT; + friend class QUICK_INDEX_INTERSECT_SELECT; friend class QUICK_ROR_INTERSECT_SELECT; friend class QUICK_GROUP_MIN_MAX_SELECT; @@ -545,6 +555,45 @@ public: READ_RECORD read_record; }; +class QUICK_INDEX_INTERSECT_SELECT : public QUICK_SELECT_I +{ + Unique *unique; +public: + QUICK_INDEX_INTERSECT_SELECT(THD *thd, TABLE *table); + ~QUICK_INDEX_INTERSECT_SELECT(); + + int init(); + int reset(void); + int get_next(); + bool reverse_sorted() { return false; } + bool unique_key_range() { return false; } + int get_type() { return QS_TYPE_INDEX_INTERSECT; } + void add_keys_and_lengths(String *key_names, String *used_lengths); + void add_info_string(String *str); + bool is_keys_used(const MY_BITMAP *fields); +#ifndef DBUG_OFF + void dbug_dump(int indent, bool verbose); +#endif + + bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range); + + /* range quick selects this index_merge read consists of */ + List quick_selects; + + /* quick select that uses clustered primary key (NULL if none) */ + QUICK_RANGE_SELECT* pk_quick_select; + + /* true if this select is currently doing a clustered PK scan */ + bool doing_pk_scan; + + MEM_ROOT alloc; + THD *thd; + int read_keys_and_merge(); + + /* used to get rows collected in Unique */ + READ_RECORD read_record; +}; + /* Rowid-Ordered Retrieval (ROR) index intersection quick select. diff --git a/sql/sql_class.h b/sql/sql_class.h index 7f3be97fe91..6d1c7ca72d3 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2949,6 +2949,7 @@ class user_var_entry DTCollation collation; }; + /* Unique -- class for unique (removing of duplicates). Puts all values to the TREE. If the tree becomes too big, @@ -2967,11 +2968,14 @@ class Unique :public Sql_alloc uchar *record_pointers; bool flush(); uint size; + uint full_size; + uint min_dupl_count; public: ulong elements; Unique(qsort_cmp2 comp_func, void *comp_func_fixed_arg, - uint size_arg, ulonglong max_in_memory_size_arg); + uint size_arg, ulonglong max_in_memory_size_arg, + uint min_dupl_count_arg= 0); ~Unique(); ulong elements_in_tree() { return tree.elements_in_tree; } inline bool unique_add(void *ptr) @@ -2983,6 +2987,9 @@ public: DBUG_RETURN(!tree_insert(&tree, ptr, 0, tree.custom_arg)); } + bool is_in_memory() { return (my_b_tell(&file) == 0); } + void close_for_expansion() { tree.flag= TREE_ONLY_DUPS; } + bool get(TABLE *table); static double get_use_cost(uint *buffer, uint nkeys, uint key_size, ulonglong max_in_memory_size); @@ -3002,6 +3009,11 @@ public: friend int unique_write_to_file(uchar* key, element_count count, Unique *unique); friend int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique); + + friend int unique_write_to_file_with_count(uchar* key, element_count count, + Unique *unique); + friend int unique_intersect_write_to_ptrs(uchar* key, element_count count, + Unique *unique); }; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8381e257e26..3f4618d4093 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13636,7 +13636,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, by clustered PK values. */ - if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE || + if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE || + quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT || quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION || quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) DBUG_RETURN(0); @@ -14042,6 +14043,7 @@ check_reverse_order: QUICK_SELECT_DESC *tmp; int quick_type= select->quick->get_type(); if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE || + quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT || quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT || quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION || quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX) @@ -16810,6 +16812,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, { quick_type= tab->select->quick->get_type(); if ((quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) || + (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) || (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) || (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION)) tab->type = JT_INDEX_MERGE; @@ -17015,6 +17018,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, { if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION || quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT || + quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT || quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) { extra.append(STRING_WITH_LEN("; Using ")); diff --git a/sql/sql_sort.h b/sql/sql_sort.h index f54b085eeda..fc4117e2767 100644 --- a/sql/sql_sort.h +++ b/sql/sql_sort.h @@ -57,6 +57,7 @@ typedef struct st_sort_param { uint addon_length; /* Length of added packed fields */ uint res_length; /* Length of records in final sorted file/buffer */ uint keys; /* Max keys / buffer */ + element_count min_dupl_count; ha_rows max_rows,examined_rows; TABLE *sort_form; /* For quicker make_sortkey */ SORT_FIELD *local_sortorder; @@ -80,4 +81,9 @@ int merge_buffers(SORTPARAM *param,IO_CACHE *from_file, IO_CACHE *to_file, uchar *sort_buffer, BUFFPEK *lastbuff,BUFFPEK *Fb, BUFFPEK *Tb,int flag); +int merge_index(SORTPARAM *param, uchar *sort_buffer, + BUFFPEK *buffpek, uint maxbuffer, + IO_CACHE *tempfile, IO_CACHE *outfile); + void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length); + diff --git a/sql/uniques.cc b/sql/uniques.cc index 3d1ea9243b9..30830059995 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -33,7 +33,6 @@ #include "mysql_priv.h" #include "sql_sort.h" - int unique_write_to_file(uchar* key, element_count count, Unique *unique) { /* @@ -45,6 +44,12 @@ int unique_write_to_file(uchar* key, element_count count, Unique *unique) return my_b_write(&unique->file, key, unique->size) ? 1 : 0; } +int unique_write_to_file_with_count(uchar* key, element_count count, Unique *unique) +{ + return my_b_write(&unique->file, key, unique->size) || + my_b_write(&unique->file, &count, sizeof(element_count)) ? 1 : 0; +} + int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique) { memcpy(unique->record_pointers, key, unique->size); @@ -52,10 +57,26 @@ int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique) return 0; } +int unique_intersect_write_to_ptrs(uchar* key, element_count count, Unique *unique) +{ + if (count >= unique->min_dupl_count) + { + memcpy(unique->record_pointers, key, unique->size); + unique->record_pointers+=unique->size; + } + return 0; +} + + Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg, - uint size_arg, ulonglong max_in_memory_size_arg) + uint size_arg, ulonglong max_in_memory_size_arg, + uint min_dupl_count_arg) :max_in_memory_size(max_in_memory_size_arg), size(size_arg), elements(0) { + min_dupl_count= min_dupl_count_arg; + full_size= size; + if (min_dupl_count_arg) + full_size+= sizeof(element_count); my_b_clear(&file); init_tree(&tree, (ulong) (max_in_memory_size / 16), 0, size, comp_func, 0, NULL, comp_func_fixed_arg); @@ -276,7 +297,11 @@ double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size, result= 2*log2_n_fact(last_tree_elems + 1.0); if (n_full_trees) result+= n_full_trees * log2_n_fact(max_elements_in_tree + 1.0); +#if 1 result /= TIME_FOR_COMPARE_ROWID; +#else + result /= TIME_FOR_COMPARE_ROWID * 10; +#endif DBUG_PRINT("info",("unique trees sizes: %u=%u*%lu + %lu", nkeys, n_full_trees, n_full_trees?max_elements_in_tree:0, @@ -327,7 +352,10 @@ bool Unique::flush() file_ptr.count=tree.elements_in_tree; file_ptr.file_pos=my_b_tell(&file); - if (tree_walk(&tree, (tree_walk_action) unique_write_to_file, + tree_walk_action action= min_dupl_count ? + (tree_walk_action) unique_write_to_file_with_count : + (tree_walk_action) unique_write_to_file; + if (tree_walk(&tree, action, (void*) this, left_root_right) || insert_dynamic(&file_ptrs, (uchar*) &file_ptr)) return 1; @@ -357,6 +385,7 @@ Unique::reset() reinit_io_cache(&file, WRITE_CACHE, 0L, 0, 1); } elements= 0; + tree.flag= 0; } /* @@ -576,14 +605,16 @@ bool Unique::get(TABLE *table) { SORTPARAM sort_param; table->sort.found_records=elements+tree.elements_in_tree; - if (my_b_tell(&file) == 0) { /* Whole tree is in memory; Don't use disk if you don't need to */ if ((record_pointers=table->sort.record_pointers= (uchar*) my_malloc(size * tree.elements_in_tree, MYF(0)))) { - (void) tree_walk(&tree, (tree_walk_action) unique_write_to_ptrs, + tree_walk_action action= min_dupl_count ? + (tree_walk_action) unique_intersect_write_to_ptrs : + (tree_walk_action) unique_write_to_ptrs; + (void) tree_walk(&tree, action, this, left_root_right); return 0; } @@ -614,7 +645,10 @@ bool Unique::get(TABLE *table) sort_param.max_rows= elements; sort_param.sort_form=table; sort_param.rec_length= sort_param.sort_length= sort_param.ref_length= - size; + sort_param.rec_length= sort_param.sort_length= sort_param.ref_length= + full_size; + sort_param.min_dupl_count= min_dupl_count; + sort_param.res_length= 0; sort_param.keys= (uint) (max_in_memory_size / sort_param.sort_length); sort_param.not_killable=1; @@ -635,8 +669,9 @@ bool Unique::get(TABLE *table) if (flush_io_cache(&file) || reinit_io_cache(&file,READ_CACHE,0L,0,0)) goto err; - if (merge_buffers(&sort_param, &file, outfile, sort_buffer, file_ptr, - file_ptr, file_ptr+maxbuffer,0)) + sort_param.res_length= sort_param.rec_length- + (min_dupl_count ? sizeof(min_dupl_count) : 0); + if (merge_index(&sort_param, sort_buffer, file_ptr, maxbuffer, &file, outfile)) goto err; error=0; err: From 1a3bb0c5c26a4f2d0ccb0ff037461bfe6804408d Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Wed, 15 Sep 2010 16:42:56 -0700 Subject: [PATCH 08/33] Fixed bug #637978. Fixed a bug in the new code for WL#24 that caused generation of an invalid index-merge access plan. --- mysql-test/r/range_vs_index_merge.result | 26 +++++++ .../r/range_vs_index_merge_innodb.result | 26 +++++++ mysql-test/t/range_vs_index_merge.test | 70 ++++++++++++++++++- sql/opt_range.cc | 39 ++++++----- 4 files changed, 143 insertions(+), 18 deletions(-) diff --git a/mysql-test/r/range_vs_index_merge.result b/mysql-test/r/range_vs_index_merge.result index 0563a0e491f..0f9c46f182d 100644 --- a/mysql-test/r/range_vs_index_merge.result +++ b/mysql-test/r/range_vs_index_merge.result @@ -1360,3 +1360,29 @@ id c1 c2 c3 select * from t1 where (c1=' 100000' or c2=' 2000000') and c3='2'; id c1 c2 c3 drop table t1; +CREATE TABLE t1 ( +a smallint DEFAULT NULL, +pk int NOT NULL AUTO_INCREMENT PRIMARY KEY, +b varchar(10) DEFAULT NULL, +c varchar(64) DEFAULT NULL, +INDEX idx1 (a), +INDEX idx2 (b), +INDEX idx3 (c) +); +SELECT COUNT(*) FROM t1 IGNORE INDEX (idx2,idx3) +WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR +(pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ; +COUNT(*) +5 +SELECT COUNT(*) FROM t1 +WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR +(pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ; +COUNT(*) +5 +EXPLAIN +SELECT COUNT(*) FROM t1 +WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR +(pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge PRIMARY,idx1,idx2,idx3 idx3,idx2,PRIMARY,idx1 67,13,4,3 NULL 8 Using sort_union(idx3,idx2,PRIMARY,idx1); Using where +DROP TABLE t1; diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result index dd97415b1dc..2251119996a 100644 --- a/mysql-test/r/range_vs_index_merge_innodb.result +++ b/mysql-test/r/range_vs_index_merge_innodb.result @@ -1361,4 +1361,30 @@ id c1 c2 c3 select * from t1 where (c1=' 100000' or c2=' 2000000') and c3='2'; id c1 c2 c3 drop table t1; +CREATE TABLE t1 ( +a smallint DEFAULT NULL, +pk int NOT NULL AUTO_INCREMENT PRIMARY KEY, +b varchar(10) DEFAULT NULL, +c varchar(64) DEFAULT NULL, +INDEX idx1 (a), +INDEX idx2 (b), +INDEX idx3 (c) +); +SELECT COUNT(*) FROM t1 IGNORE INDEX (idx2,idx3) +WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR +(pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ; +COUNT(*) +5 +SELECT COUNT(*) FROM t1 +WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR +(pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ; +COUNT(*) +5 +EXPLAIN +SELECT COUNT(*) FROM t1 +WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR +(pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge PRIMARY,idx1,idx2,idx3 idx3,idx2,idx1,PRIMARY 67,13,3,4 NULL 9 Using sort_union(idx3,idx2,idx1,PRIMARY); Using where +DROP TABLE t1; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/t/range_vs_index_merge.test b/mysql-test/t/range_vs_index_merge.test index aa5f4620ffe..f57fced6da6 100755 --- a/mysql-test/t/range_vs_index_merge.test +++ b/mysql-test/t/range_vs_index_merge.test @@ -846,7 +846,75 @@ select * from t1 where (c1=' 100000' or c2=' 2000000') and c3='2'; drop table t1; +# +# Bug #637978: invalid index merge access plan causes to wrong results +# +CREATE TABLE t1 ( + a smallint DEFAULT NULL, + pk int NOT NULL AUTO_INCREMENT PRIMARY KEY, + b varchar(10) DEFAULT NULL, + c varchar(64) DEFAULT NULL, + INDEX idx1 (a), + INDEX idx2 (b), + INDEX idx3 (c) +); +--disable_query_log +--disable_result_log +INSERT INTO t1 VALUES +(30371,99001,'dl','e'),(3,99002,'Ohio','t'),(9,99003,'Delaware','xb'), +(0,99004,'Pennsylvan','i'),(-199,99005,'y','d'),(0,99006,'with','Rhode Island'), +(3,99007,'km','qkmiimdxbdljsejtsfrvwlrgacinbmfuosflnenlpomkmvbig'), +(22860,99008,'ovqkmiimdx','uovqkmiimdxbdljsejtsfrvwlrgacinbmfuosflnenlpomkmvbig'), +(212,99009,'f','p'),(NULL,99010,'i','k'),(20426,99011,'Vermont','New York'), +(0,99012,'Oregon','w'),(31831,99013,'s','isrcijpuovqkmiimdxbdljsejtsfrvwl'), +(123,99014,'t','p'),(32767,99015,'q','Maine'), +(NULL,99016,'know','qqqpisrcijpuovqkmiimdxbdljsejtsfrvwlrgacinbmfuosflnenlpo'), +(1,99017,'going','North Carolina'),(-717,99018,'ad','Indiana'), +(32767,99019,'Maryland','aa'),(31280,99020,'Nebraska','Colorado'), +(0,99021,'q','Ohio'), +(5989,99022,'rovaadtqqq','lrovaadtqqqpisrcijpuovqkmiimdxbdljsejtsfrvwlrgacinb'), +(89,99023,'n','Pennsylvania'),(0,99024,'Florida','c'),(97,99025,'Maine','y'), +(149,99026,'xaemnl','Idaho'),(NULL,99027,'h','y'),(26276,99028,'going','New York'), +(242,99029,'bdhxaemnlr','sbdhxaemnlrovaadtqqqpisrcijpuovqkmiimdxb'), +(32767,99030,'if','a'),(26581,99031,'Arizona','q'),(45,99032,'ysazsbdhxa','f'), +(0,99033,'qv','s'),(NULL,99034,'Louisiana','lqvfysazsbdhxaemnlrovaadtqqqpisrc'), +(160,99035,'Connecticu','x'),(23241,99036,'lx','q'),(0,99037,'u','Colorado'), +(-19141,99038,'w','h'),(218,99039,'s','uo'),(4,99040,'Montana','Oklahoma'), +(97,99041,'r','ls'),(32767,99042,'q','v'),(7,99043,'mlsuownlnl','did'), +(NULL,99044,'ui','i'),(2,99045,'to','I\'ll'),(0,99046,'Nevada','g'), +(3251,99047,'y','New York'),(0,99048,'wyttuimlsu','you\'re'), +(7,99049,'he','South Carolina'),(32767,99050,'s','right'), +(172,99051,'Arizona','e'),(0,99052,'x','lxmvwyttuimlsuownlnlxklq'), +(NULL,99053,'f','wfjlxmvwyttuimlsuownlnlxklqvfysazs'),(44,99054,'s','n'), +(-17561,99055,'me','wm'),(88,99056,'y','my'),(7313,99057,'jx','New Hampshire'), +(63,99058,'zl','South Carolina'),(9,99059,'ma','Illinois'), +(6,99060,'lamazljxpg','like'),(17021,99061,'x','v'),(0,99062,'New Mexico','j'), +(179,99427,'fliq','because'), +(107,99063,'Virginia','Mississippi'), +(0,99064,'si','to'),(113,99065,'Illinois','Kansas'),(20808,99066,'tsi','d'), +(-15372,99067,'d','vdftsidjtvulamazljxpgiwmbnmwfjlxmvwyttuimlsuownlnl'), +(0,99068,'y','then'),(2,99069,'all','b'),(NULL,99070,'by','Wisconsin'), +(4,99071,'about','right'),(5,99072,'m','s'),(0,99073,'e','Pennsylvania'), +(-28284,99074,'x','f'),(1,99075,'Rhode Isla','Georgia'),(NULL,99076,'p','was'), +(168,99077,'Tennessee','Minnesota'),(18349,99078,'x','Rhode Island'), +(5,99079,'as','d'),(12217,99080,'c','i'),(0,99081,'rdvdxboydm','s'), +(19132,99082,'her','jerdvdxboydmpefbiesqbyyvdftsidjtvulamazljxpgiwmbn'), +(0,99083,'all','jhjerdvdxboydmpefbiesqbyyvdftsidjtvulamazljx'), +(32767,99084,'s','flj'),(-4947,99085,'something','Vermont'), +(0,99086,'cjfljhjerd','Washington'); +--enable_query_log +--enable_result_log +SELECT COUNT(*) FROM t1 IGNORE INDEX (idx2,idx3) + WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR + (pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ; +SELECT COUNT(*) FROM t1 + WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR + (pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ; +EXPLAIN +SELECT COUNT(*) FROM t1 + WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR + (pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ; - +DROP TABLE t1; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 9fac099855e..1342c1ef331 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -890,10 +890,12 @@ public: int and_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree, SEL_IMERGE *new_imerge); int or_sel_tree_with_checks(RANGE_OPT_PARAM *param, + uint n_init_trees, SEL_TREE *new_tree, bool is_first_check_pass, bool *is_last_check_pass); int or_sel_imerge_with_checks(RANGE_OPT_PARAM *param, + uint n_init_trees, SEL_IMERGE* imerge, bool is_first_check_pass, bool *is_last_check_pass); @@ -1025,7 +1027,8 @@ int SEL_IMERGE::and_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree, SYNOPSIS or_sel_tree_with_checks() - param Context info for the operation + param Context info for the operation + n_trees Number of trees in this imerge to check for oring tree SEL_TREE whose range part is to be ored is_first_check_pass <=> the first call of the function for this imerge is_last_check_pass OUT <=> no more calls of the function for this imerge @@ -1075,14 +1078,14 @@ int SEL_IMERGE::and_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree, */ int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param, + uint n_trees, SEL_TREE *tree, bool is_first_check_pass, bool *is_last_check_pass) { - *is_last_check_pass= TRUE; - for (SEL_TREE** or_tree = trees; - or_tree != trees_next; - or_tree++) + *is_last_check_pass= TRUE; + SEL_TREE** or_tree = trees; + for (uint i= 0; i < n_trees; i++, or_tree++) { SEL_TREE *result= 0; key_map result_keys; @@ -1116,7 +1119,7 @@ int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param, (key1)->test_use_count(key1); } #endif - } + } } } else if(is_first_check_pass) @@ -1152,8 +1155,9 @@ int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param, Perform OR operation on this imerge and and another imerge SYNOPSIS - or_sel_tree_with_checks() - param Context info for the operation + or_sel_imerge_with_checks() + param Context info for the operation + n_trees Number of trees in this imerge to check for oring imerge The second operand of the operation is_first_check_pass <=> the first call of the function for this imerge is_last_check_pass OUT <=> no more calls of the function for this imerge @@ -1176,18 +1180,19 @@ int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param, */ int SEL_IMERGE::or_sel_imerge_with_checks(RANGE_OPT_PARAM *param, + uint n_trees, SEL_IMERGE* imerge, bool is_first_check_pass, bool *is_last_check_pass) { *is_last_check_pass= TRUE; - for (SEL_TREE** tree= imerge->trees; - tree != imerge->trees_next; - tree++) + SEL_TREE** tree= imerge->trees; + for (uint i= 0; i < n_trees; i++, tree++) { uint rc; - bool is_last; - rc= or_sel_tree_with_checks(param, *tree, is_first_check_pass, &is_last); + bool is_last= TRUE; + rc= or_sel_tree_with_checks(param, n_trees, *tree, + is_first_check_pass, &is_last); if (!is_last) *is_last_check_pass= FALSE; if (rc) @@ -1368,7 +1373,7 @@ int imerge_list_or_list(RANGE_OPT_PARAM *param, im1->empty(); im1->push_back(imerge); - rc= imerge->or_sel_imerge_with_checks(param, im2->head(), + rc= imerge->or_sel_imerge_with_checks(param, elems, im2->head(), TRUE, &is_last_check_pass); if (rc) { @@ -1386,7 +1391,7 @@ int imerge_list_or_list(RANGE_OPT_PARAM *param, if (new_imerge) { is_last_check_pass= TRUE; - rc= new_imerge->or_sel_imerge_with_checks(param, im2->head(), + rc= new_imerge->or_sel_imerge_with_checks(param, elems, im2->head(), FALSE, &is_last_check_pass); if (!rc) im1->push_back(new_imerge); @@ -1463,14 +1468,14 @@ int imerge_list_or_tree(RANGE_OPT_PARAM *param, if (or_tree) { uint elems= imerge->trees_next-imerge->trees; - rc= imerge->or_sel_tree_with_checks(param, or_tree, + rc= imerge->or_sel_tree_with_checks(param, elems, or_tree, TRUE, &is_last_check_pass); if (!is_last_check_pass) { SEL_IMERGE *new_imerge= new SEL_IMERGE(imerge, elems, param); if (new_imerge) { - rc1= new_imerge->or_sel_tree_with_checks(param, or_tree, + rc1= new_imerge->or_sel_tree_with_checks(param, elems, or_tree, FALSE, &is_last_check_pass); if (!rc1) additional_merges.push_back(new_imerge); From f0f9ab69c7c75241ce0a28a33132e504c39f4a6d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 19 Nov 2010 12:17:57 +0100 Subject: [PATCH 09/33] Mbug#677407 / MySQL Bug#48883: Stale data from INNODB_LOCKS table. The logic for how to check when to update the table cache for INNODB_LOCKS with real data was flawed. This could result in both not updating the cache often enough (when the table is queried repeatedly with less than 100 milliseconds in-between) resulting in stale data; as well as updating too often (when multiple queries against the table start at around the same time). This caused occasional test failures in innodb_information_schema. Fix by updating the "last updated" timestamp in the right place, when the cache is updated, not when it is read. --- storage/innodb_plugin/trx/trx0i_s.c | 33 +++++++++-------------------- storage/xtradb/trx/trx0i_s.c | 33 +++++++++-------------------- 2 files changed, 20 insertions(+), 46 deletions(-) diff --git a/storage/innodb_plugin/trx/trx0i_s.c b/storage/innodb_plugin/trx/trx0i_s.c index 5bc8302d0c0..c0b9a73a68c 100644 --- a/storage/innodb_plugin/trx/trx0i_s.c +++ b/storage/innodb_plugin/trx/trx0i_s.c @@ -157,10 +157,6 @@ struct trx_i_s_cache_struct { ullint last_read; /*!< last time the cache was read; measured in microseconds since epoch */ - mutex_t last_read_mutex;/*!< mutex protecting the - last_read member - it is updated - inside a shared lock of the - rw_lock member */ i_s_table_cache_t innodb_trx; /*!< innodb_trx table */ i_s_table_cache_t innodb_locks; /*!< innodb_locks table */ i_s_table_cache_t innodb_lock_waits;/*!< innodb_lock_waits table */ @@ -1101,13 +1097,6 @@ can_cache_be_updated( { ullint now; - /* Here we read cache->last_read without acquiring its mutex - because last_read is only updated when a shared rw lock on the - whole cache is being held (see trx_i_s_cache_end_read()) and - we are currently holding an exclusive rw lock on the cache. - So it is not possible for last_read to be updated while we are - reading it. */ - #ifdef UNIV_SYNC_DEBUG ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_EX)); #endif @@ -1205,6 +1194,12 @@ trx_i_s_possibly_fetch_data_into_cache( /*===================================*/ trx_i_s_cache_t* cache) /*!< in/out: cache */ { + ullint now; + +#ifdef UNIV_SYNC_DEBUG + ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_EX)); +#endif + if (!can_cache_be_updated(cache)) { return(1); @@ -1217,6 +1212,10 @@ trx_i_s_possibly_fetch_data_into_cache( mutex_exit(&kernel_mutex); + /* update cache last read time */ + now = ut_time_us(NULL); + cache->last_read = now; + return(0); } @@ -1247,16 +1246,12 @@ trx_i_s_cache_init( release kernel_mutex release trx_i_s_cache_t::rw_lock acquire trx_i_s_cache_t::rw_lock, S - acquire trx_i_s_cache_t::last_read_mutex - release trx_i_s_cache_t::last_read_mutex release trx_i_s_cache_t::rw_lock */ rw_lock_create(&cache->rw_lock, SYNC_TRX_I_S_RWLOCK); cache->last_read = 0; - mutex_create(&cache->last_read_mutex, SYNC_TRX_I_S_LAST_READ); - table_cache_init(&cache->innodb_trx, sizeof(i_s_trx_row_t)); table_cache_init(&cache->innodb_locks, sizeof(i_s_locks_row_t)); table_cache_init(&cache->innodb_lock_waits, @@ -1307,18 +1302,10 @@ trx_i_s_cache_end_read( /*===================*/ trx_i_s_cache_t* cache) /*!< in: cache */ { - ullint now; - #ifdef UNIV_SYNC_DEBUG ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_SHARED)); #endif - /* update cache last read time */ - now = ut_time_us(NULL); - mutex_enter(&cache->last_read_mutex); - cache->last_read = now; - mutex_exit(&cache->last_read_mutex); - rw_lock_s_unlock(&cache->rw_lock); } diff --git a/storage/xtradb/trx/trx0i_s.c b/storage/xtradb/trx/trx0i_s.c index 5bc8302d0c0..c0b9a73a68c 100644 --- a/storage/xtradb/trx/trx0i_s.c +++ b/storage/xtradb/trx/trx0i_s.c @@ -157,10 +157,6 @@ struct trx_i_s_cache_struct { ullint last_read; /*!< last time the cache was read; measured in microseconds since epoch */ - mutex_t last_read_mutex;/*!< mutex protecting the - last_read member - it is updated - inside a shared lock of the - rw_lock member */ i_s_table_cache_t innodb_trx; /*!< innodb_trx table */ i_s_table_cache_t innodb_locks; /*!< innodb_locks table */ i_s_table_cache_t innodb_lock_waits;/*!< innodb_lock_waits table */ @@ -1101,13 +1097,6 @@ can_cache_be_updated( { ullint now; - /* Here we read cache->last_read without acquiring its mutex - because last_read is only updated when a shared rw lock on the - whole cache is being held (see trx_i_s_cache_end_read()) and - we are currently holding an exclusive rw lock on the cache. - So it is not possible for last_read to be updated while we are - reading it. */ - #ifdef UNIV_SYNC_DEBUG ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_EX)); #endif @@ -1205,6 +1194,12 @@ trx_i_s_possibly_fetch_data_into_cache( /*===================================*/ trx_i_s_cache_t* cache) /*!< in/out: cache */ { + ullint now; + +#ifdef UNIV_SYNC_DEBUG + ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_EX)); +#endif + if (!can_cache_be_updated(cache)) { return(1); @@ -1217,6 +1212,10 @@ trx_i_s_possibly_fetch_data_into_cache( mutex_exit(&kernel_mutex); + /* update cache last read time */ + now = ut_time_us(NULL); + cache->last_read = now; + return(0); } @@ -1247,16 +1246,12 @@ trx_i_s_cache_init( release kernel_mutex release trx_i_s_cache_t::rw_lock acquire trx_i_s_cache_t::rw_lock, S - acquire trx_i_s_cache_t::last_read_mutex - release trx_i_s_cache_t::last_read_mutex release trx_i_s_cache_t::rw_lock */ rw_lock_create(&cache->rw_lock, SYNC_TRX_I_S_RWLOCK); cache->last_read = 0; - mutex_create(&cache->last_read_mutex, SYNC_TRX_I_S_LAST_READ); - table_cache_init(&cache->innodb_trx, sizeof(i_s_trx_row_t)); table_cache_init(&cache->innodb_locks, sizeof(i_s_locks_row_t)); table_cache_init(&cache->innodb_lock_waits, @@ -1307,18 +1302,10 @@ trx_i_s_cache_end_read( /*===================*/ trx_i_s_cache_t* cache) /*!< in: cache */ { - ullint now; - #ifdef UNIV_SYNC_DEBUG ut_a(rw_lock_own(&cache->rw_lock, RW_LOCK_SHARED)); #endif - /* update cache last read time */ - now = ut_time_us(NULL); - mutex_enter(&cache->last_read_mutex); - cache->last_read = now; - mutex_exit(&cache->last_read_mutex); - rw_lock_s_unlock(&cache->rw_lock); } From 80377bbf6dadd1772f6b4f4d4258892a023d586a Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Wed, 1 Dec 2010 23:39:39 -0800 Subject: [PATCH 10/33] MWL #21: "index_merge: non-ROR intersection". The second (final) patch. --- mysql-test/include/index_merge1.inc | 2 +- mysql-test/r/index_intersect.result | 921 +++++++++++++++++ mysql-test/r/index_intersect_innodb.result | 923 ++++++++++++++++++ mysql-test/r/index_merge_innodb.result | 3 + mysql-test/r/index_merge_myisam.result | 31 +- mysql-test/r/order_by.result | 4 +- mysql-test/r/range_vs_index_merge.result | 163 +--- .../r/range_vs_index_merge_innodb.result | 193 ++-- mysql-test/r/subselect.result | 4 - mysql-test/r/variables.result | 1 + mysql-test/t/index_intersect.test | 385 ++++++++ mysql-test/t/index_intersect_innodb.test | 7 + mysql-test/t/index_merge_innodb.test | 7 + mysql-test/t/index_merge_myisam.test | 8 +- mysql-test/t/order_by.test | 2 +- mysql-test/t/range_vs_index_merge.test | 63 +- mysql-test/t/variables.test | 1 + sql/filesort.cc | 1 + sql/mysql_priv.h | 15 +- sql/mysqld.cc | 9 +- sql/opt_range.cc | 918 +++++++++++++---- sql/opt_range.h | 8 +- sql/sql_class.h | 10 +- sql/sql_select.cc | 9 +- sql/table.h | 2 +- sql/uniques.cc | 50 +- sql/unireg.h | 2 +- 27 files changed, 3237 insertions(+), 505 deletions(-) create mode 100644 mysql-test/r/index_intersect.result create mode 100644 mysql-test/r/index_intersect_innodb.result create mode 100644 mysql-test/t/index_intersect.test create mode 100644 mysql-test/t/index_intersect_innodb.test diff --git a/mysql-test/include/index_merge1.inc b/mysql-test/include/index_merge1.inc index d137b0957c0..b865397bd26 100644 --- a/mysql-test/include/index_merge1.inc +++ b/mysql-test/include/index_merge1.inc @@ -539,7 +539,7 @@ INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; -SET SESSION sort_buffer_size=1; +SET SESSION sort_buffer_size=1024*8; EXPLAIN SELECT * FROM t1 FORCE INDEX(a,b) WHERE a LIKE 'a%' OR b LIKE 'b%' ORDER BY a,b; diff --git a/mysql-test/r/index_intersect.result b/mysql-test/r/index_intersect.result new file mode 100644 index 00000000000..1a89fe897e7 --- /dev/null +++ b/mysql-test/r/index_intersect.result @@ -0,0 +1,921 @@ +DROP TABLE IF EXISTS t1,t2,t3,t4; +DROP DATABASE IF EXISTS world; +set names utf8; +CREATE DATABASE world; +use world; +CREATE TABLE Country ( +Code char(3) NOT NULL default '', +Name char(52) NOT NULL default '', +SurfaceArea float(10,2) NOT NULL default '0.00', +Population int(11) NOT NULL default '0', +Capital int(11) default NULL, +PRIMARY KEY (Code), +UNIQUE INDEX (Name) +); +CREATE TABLE City ( +ID int(11) NOT NULL auto_increment, +Name char(35) NOT NULL default '', +Country char(3) NOT NULL default '', +Population int(11) NOT NULL default '0', +PRIMARY KEY (ID), +INDEX (Population), +INDEX (Country) +); +CREATE TABLE CountryLanguage ( +Country char(3) NOT NULL default '', +Language char(30) NOT NULL default '', +Percentage float(3,1) NOT NULL default '0.0', +PRIMARY KEY (Country, Language), +INDEX (Percentage) +); +SELECT COUNT(*) FROM Country; +COUNT(*) +239 +SELECT COUNT(*) FROM City; +COUNT(*) +4079 +SELECT COUNT(*) FROM CountryLanguage; +COUNT(*) +984 +CREATE INDEX Name ON City(Name); +SET SESSION optimizer_switch='index_merge_sort_intersection=on'; +SELECT COUNT(*) FROM City; +COUNT(*) +4079 +SELECT COUNT(*) FROM City WHERE Name LIKE 'C%'; +COUNT(*) +281 +SELECT COUNT(*) FROM City WHERE Name LIKE 'M%'; +COUNT(*) +301 +SELECT COUNT(*) FROM City WHERE Population > 1000000; +COUNT(*) +237 +SELECT COUNT(*) FROM City WHERE Population > 500000; +COUNT(*) +539 +SELECT COUNT(*) FROM City WHERE Population > 300000; +COUNT(*) +1062 +SELECT COUNT(*) FROM City WHERE Population > 5000000; +COUNT(*) +24 +EXPLAIN +SELECT * FROM City WHERE +Name LIKE 'C%' AND Population > 1000000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Name Population,Name 4,35 NULL 9 Using sort_intersect(Population,Name); Using where +EXPLAIN +SELECT * FROM City WHERE +Name LIKE 'M%' AND Population > 500000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Name Population,Name 4,35 NULL 21 Using sort_intersect(Population,Name); Using where +EXPLAIN +SELECT * FROM City +WHERE Name LIKE 'M%' AND Population > 300000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Name Name 35 NULL 164 Using where +EXPLAIN +SELECT * FROM City +WHERE Name LIKE 'M%' AND Population > 5000000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Name Population 4 NULL 25 Using where +SELECT * FROM City USE INDEX () +WHERE Name LIKE 'C%' AND Population > 1000000; +ID Name Country Population +71 Córdoba ARG 1157507 +151 Chittagong BGD 1392860 +212 Curitiba BRA 1584232 +608 Cairo EGY 6789479 +712 Cape Town ZAF 2352121 +926 Conakry GIN 1090610 +1026 Calcutta [Kolkata] IND 4399819 +1027 Chennai (Madras) IND 3841396 +1892 Chongqing CHN 6351600 +1898 Chengdu CHN 3361500 +1900 Changchun CHN 2812000 +1910 Changsha CHN 1809800 +2258 Cali COL 2077386 +2485 Casablanca MAR 2940623 +2515 Ciudad de México MEX 8591309 +3539 Caracas VEN 1975294 +3795 Chicago USA 2896016 +SELECT * FROM City +WHERE Name LIKE 'C%' AND Population > 1000000; +ID Name Country Population +71 Córdoba ARG 1157507 +151 Chittagong BGD 1392860 +212 Curitiba BRA 1584232 +608 Cairo EGY 6789479 +712 Cape Town ZAF 2352121 +926 Conakry GIN 1090610 +1026 Calcutta [Kolkata] IND 4399819 +1027 Chennai (Madras) IND 3841396 +1892 Chongqing CHN 6351600 +1898 Chengdu CHN 3361500 +1900 Changchun CHN 2812000 +1910 Changsha CHN 1809800 +2258 Cali COL 2077386 +2485 Casablanca MAR 2940623 +2515 Ciudad de México MEX 8591309 +3539 Caracas VEN 1975294 +3795 Chicago USA 2896016 +SELECT * FROM City USE INDEX () +WHERE Name LIKE 'M%' AND Population > 500000; +ID Name Country Population +77 Mar del Plata ARG 512880 +131 Melbourne AUS 2865329 +215 Manaus BRA 1255049 +223 Maceió BRA 786288 +653 Madrid ESP 2879052 +658 Málaga ESP 530553 +766 Manila PHL 1581082 +942 Medan IDN 1843919 +947 Malang IDN 716862 +1024 Mumbai (Bombay) IND 10500000 +1042 Madurai IND 977856 +1051 Meerut IND 753778 +1366 Mosul IRQ 879000 +1381 Mashhad IRN 1887405 +1465 Milano ITA 1300977 +1810 Montréal CAN 1016376 +1816 Mississauga CAN 608072 +1945 Mudanjiang CHN 570000 +2259 Medellín COL 1861265 +2300 Mbuji-Mayi COD 806475 +2440 Monrovia LBR 850000 +2487 Marrakech MAR 621914 +2523 Monterrey MEX 1108499 +2526 Mexicali MEX 764902 +2530 Mérida MEX 703324 +2537 Morelia MEX 619958 +2698 Maputo MOZ 1018938 +2711 Mandalay MMR 885300 +2734 Managua NIC 959000 +2826 Multan PAK 1182441 +2975 Marseille FRA 798430 +3070 Munich [München] DEU 1194560 +3175 Mekka SAU 965700 +3176 Medina SAU 608300 +3214 Mogadishu SOM 997000 +3364 Mersin (Içel) TUR 587212 +3434 Mykolajiv UKR 508000 +3492 Montevideo URY 1236000 +3520 Minsk BLR 1674000 +3540 Maracaíbo VEN 1304776 +3580 Moscow RUS 8389200 +3810 Memphis USA 650100 +3811 Milwaukee USA 596974 +SELECT * FROM City +WHERE Name LIKE 'M%' AND Population > 500000; +ID Name Country Population +77 Mar del Plata ARG 512880 +131 Melbourne AUS 2865329 +215 Manaus BRA 1255049 +223 Maceió BRA 786288 +653 Madrid ESP 2879052 +658 Málaga ESP 530553 +766 Manila PHL 1581082 +942 Medan IDN 1843919 +947 Malang IDN 716862 +1024 Mumbai (Bombay) IND 10500000 +1042 Madurai IND 977856 +1051 Meerut IND 753778 +1366 Mosul IRQ 879000 +1381 Mashhad IRN 1887405 +1465 Milano ITA 1300977 +1810 Montréal CAN 1016376 +1816 Mississauga CAN 608072 +1945 Mudanjiang CHN 570000 +2259 Medellín COL 1861265 +2300 Mbuji-Mayi COD 806475 +2440 Monrovia LBR 850000 +2487 Marrakech MAR 621914 +2523 Monterrey MEX 1108499 +2526 Mexicali MEX 764902 +2530 Mérida MEX 703324 +2537 Morelia MEX 619958 +2698 Maputo MOZ 1018938 +2711 Mandalay MMR 885300 +2734 Managua NIC 959000 +2826 Multan PAK 1182441 +2975 Marseille FRA 798430 +3070 Munich [München] DEU 1194560 +3175 Mekka SAU 965700 +3176 Medina SAU 608300 +3214 Mogadishu SOM 997000 +3364 Mersin (Içel) TUR 587212 +3434 Mykolajiv UKR 508000 +3492 Montevideo URY 1236000 +3520 Minsk BLR 1674000 +3540 Maracaíbo VEN 1304776 +3580 Moscow RUS 8389200 +3810 Memphis USA 650100 +3811 Milwaukee USA 596974 +SELECT * FROM City USE INDEX () +WHERE Name LIKE 'M%' AND Population > 300000; +ID Name Country Population +77 Mar del Plata ARG 512880 +80 Merlo ARG 463846 +83 Moreno ARG 356993 +87 Morón ARG 349246 +131 Melbourne AUS 2865329 +215 Manaus BRA 1255049 +223 Maceió BRA 786288 +250 Mauá BRA 375055 +256 Moji das Cruzes BRA 339194 +462 Manchester GBR 430000 +653 Madrid ESP 2879052 +658 Málaga ESP 530553 +661 Murcia ESP 353504 +766 Manila PHL 1581082 +778 Makati PHL 444867 +781 Marikina PHL 391170 +783 Muntinlupa PHL 379310 +786 Malabon PHL 338855 +942 Medan IDN 1843919 +947 Malang IDN 716862 +962 Manado IDN 332288 +963 Mataram IDN 306600 +1024 Mumbai (Bombay) IND 10500000 +1042 Madurai IND 977856 +1051 Meerut IND 753778 +1074 Mysore IND 480692 +1081 Moradabad IND 429214 +1098 Malegaon IND 342595 +1366 Mosul IRQ 879000 +1381 Mashhad IRN 1887405 +1465 Milano ITA 1300977 +1559 Matsuyama JPN 466133 +1560 Matsudo JPN 461126 +1578 Machida JPN 364197 +1595 Miyazaki JPN 303784 +1810 Montréal CAN 1016376 +1816 Mississauga CAN 608072 +1882 Mombasa KEN 461753 +1945 Mudanjiang CHN 570000 +2005 Ma´anshan CHN 305421 +2259 Medellín COL 1861265 +2267 Manizales COL 337580 +2300 Mbuji-Mayi COD 806475 +2348 Masan KOR 441242 +2440 Monrovia LBR 850000 +2454 Macao MAC 437500 +2487 Marrakech MAR 621914 +2491 Meknès MAR 460000 +2523 Monterrey MEX 1108499 +2526 Mexicali MEX 764902 +2530 Mérida MEX 703324 +2537 Morelia MEX 619958 +2554 Matamoros MEX 416428 +2557 Mazatlán MEX 380265 +2698 Maputo MOZ 1018938 +2699 Matola MOZ 424662 +2711 Mandalay MMR 885300 +2712 Moulmein (Mawlamyine) MMR 307900 +2734 Managua NIC 959000 +2756 Mushin NGA 333200 +2757 Maiduguri NGA 320000 +2826 Multan PAK 1182441 +2975 Marseille FRA 798430 +3070 Munich [München] DEU 1194560 +3086 Mannheim DEU 307730 +3175 Mekka SAU 965700 +3176 Medina SAU 608300 +3214 Mogadishu SOM 997000 +3364 Mersin (Içel) TUR 587212 +3371 Malatya TUR 330312 +3434 Mykolajiv UKR 508000 +3435 Mariupol UKR 490000 +3438 Makijivka UKR 384000 +3492 Montevideo URY 1236000 +3520 Minsk BLR 1674000 +3522 Mogiljov BLR 356000 +3540 Maracaíbo VEN 1304776 +3545 Maracay VEN 444443 +3547 Maturín VEN 319726 +3580 Moscow RUS 8389200 +3622 Magnitogorsk RUS 427900 +3625 Murmansk RUS 376300 +3636 Mahat?kala RUS 332800 +3810 Memphis USA 650100 +3811 Milwaukee USA 596974 +3834 Mesa USA 396375 +3837 Minneapolis USA 382618 +3839 Miami USA 362470 +SELECT * FROM City +WHERE Name LIKE 'M%' AND Population > 300000; +ID Name Country Population +2454 Macao MAC 437500 +223 Maceió BRA 786288 +1578 Machida JPN 364197 +653 Madrid ESP 2879052 +1042 Madurai IND 977856 +3622 Magnitogorsk RUS 427900 +3636 Mahat?kala RUS 332800 +2757 Maiduguri NGA 320000 +778 Makati PHL 444867 +3438 Makijivka UKR 384000 +786 Malabon PHL 338855 +658 Málaga ESP 530553 +947 Malang IDN 716862 +3371 Malatya TUR 330312 +1098 Malegaon IND 342595 +962 Manado IDN 332288 +2734 Managua NIC 959000 +215 Manaus BRA 1255049 +462 Manchester GBR 430000 +2711 Mandalay MMR 885300 +766 Manila PHL 1581082 +2267 Manizales COL 337580 +3086 Mannheim DEU 307730 +2698 Maputo MOZ 1018938 +77 Mar del Plata ARG 512880 +3540 Maracaíbo VEN 1304776 +3545 Maracay VEN 444443 +781 Marikina PHL 391170 +3435 Mariupol UKR 490000 +2487 Marrakech MAR 621914 +2975 Marseille FRA 798430 +2348 Masan KOR 441242 +1381 Mashhad IRN 1887405 +2554 Matamoros MEX 416428 +963 Mataram IDN 306600 +2699 Matola MOZ 424662 +1560 Matsudo JPN 461126 +1559 Matsuyama JPN 466133 +3547 Maturín VEN 319726 +250 Mauá BRA 375055 +2557 Mazatlán MEX 380265 +2005 Ma´anshan CHN 305421 +2300 Mbuji-Mayi COD 806475 +942 Medan IDN 1843919 +2259 Medellín COL 1861265 +3176 Medina SAU 608300 +1051 Meerut IND 753778 +3175 Mekka SAU 965700 +2491 Meknès MAR 460000 +131 Melbourne AUS 2865329 +3810 Memphis USA 650100 +2530 Mérida MEX 703324 +80 Merlo ARG 463846 +3364 Mersin (Içel) TUR 587212 +3834 Mesa USA 396375 +2526 Mexicali MEX 764902 +3839 Miami USA 362470 +1465 Milano ITA 1300977 +3811 Milwaukee USA 596974 +3837 Minneapolis USA 382618 +3520 Minsk BLR 1674000 +1816 Mississauga CAN 608072 +1595 Miyazaki JPN 303784 +3214 Mogadishu SOM 997000 +3522 Mogiljov BLR 356000 +256 Moji das Cruzes BRA 339194 +1882 Mombasa KEN 461753 +2440 Monrovia LBR 850000 +2523 Monterrey MEX 1108499 +3492 Montevideo URY 1236000 +1810 Montréal CAN 1016376 +1081 Moradabad IND 429214 +2537 Morelia MEX 619958 +83 Moreno ARG 356993 +87 Morón ARG 349246 +3580 Moscow RUS 8389200 +1366 Mosul IRQ 879000 +2712 Moulmein (Mawlamyine) MMR 307900 +1945 Mudanjiang CHN 570000 +2826 Multan PAK 1182441 +1024 Mumbai (Bombay) IND 10500000 +3070 Munich [München] DEU 1194560 +783 Muntinlupa PHL 379310 +661 Murcia ESP 353504 +3625 Murmansk RUS 376300 +2756 Mushin NGA 333200 +3434 Mykolajiv UKR 508000 +1074 Mysore IND 480692 +SELECT * FROM City USE INDEX () +WHERE Name LIKE 'M%' AND Population > 5000000; +ID Name Country Population +1024 Mumbai (Bombay) IND 10500000 +3580 Moscow RUS 8389200 +SELECT * FROM City +WHERE Name LIKE 'M%' AND Population > 5000000; +ID Name Country Population +3580 Moscow RUS 8389200 +1024 Mumbai (Bombay) IND 10500000 +SELECT COUNT(*) FROM City WHERE Name BETWEEN 'M' AND 'N'; +COUNT(*) +301 +SELECT COUNT(*) FROM City WHERE Name BETWEEN 'G' AND 'J'; +COUNT(*) +408 +SELECT COUNT(*) FROM City WHERE Population > 1000000; +COUNT(*) +237 +SELECT COUNT(*) FROM City WHERE Population > 700000; +COUNT(*) +358 +SELECT COUNT(*) FROM City WHERE Population > 500000; +COUNT(*) +539 +SELECT COUNT(*) FROM City WHERE Country LIKE 'C%'; +COUNT(*) +551 +SELECT COUNT(*) FROM City WHERE Country LIKE 'L%'; +COUNT(*) +29 +EXPLAIN +SELECT * FROM City +WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Country,Name Population,Name 4,35 NULL 9 Using sort_intersect(Population,Name); Using where +EXPLAIN +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'L%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Country,Name Country 3 NULL 28 Using where +EXPLAIN +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Country,Name Country,Name 3,35 NULL 29 Using sort_intersect(Country,Name); Using where +SELECT * FROM City USE INDEX () +WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; +ID Name Country Population +1810 Montréal CAN 1016376 +2259 Medellín COL 1861265 +SELECT * FROM City +WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; +ID Name Country Population +1810 Montréal CAN 1016376 +2259 Medellín COL 1861265 +SELECT * FROM City USE INDEX () +WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; +ID Name Country Population +2516 Guadalajara MEX 1647720 +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; +ID Name Country Population +2516 Guadalajara MEX 1647720 +SELECT * FROM City USE INDEX () +WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; +ID Name Country Population +1895 Harbin CHN 4289800 +1905 Hangzhou CHN 2190500 +1914 Guiyang CHN 1465200 +1916 Hefei CHN 1369100 +1927 Hohhot CHN 916700 +1928 Handan CHN 840000 +1937 Huainan CHN 700000 +1950 Hegang CHN 520000 +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; +ID Name Country Population +1895 Harbin CHN 4289800 +1905 Hangzhou CHN 2190500 +1914 Guiyang CHN 1465200 +1916 Hefei CHN 1369100 +1927 Hohhot CHN 916700 +1928 Handan CHN 840000 +1937 Huainan CHN 700000 +1950 Hegang CHN 520000 +SELECT COUNT(*) FROM City WHERE ID BETWEEN 500 AND 999; +COUNT(*) +500 +SELECT COUNT(*) FROM City WHERE ID BETWEEN 3500 AND 3999; +COUNT(*) +500 +SELECT COUNT(*) FROM City WHERE ID BETWEEN 1 AND 1000; +COUNT(*) +1000 +SELECT COUNT(*) FROM City WHERE Population > 700000; +COUNT(*) +358 +SELECT COUNT(*) FROM City WHERE Population > 1000000; +COUNT(*) +237 +SELECT COUNT(*) FROM City WHERE Population > 300000; +COUNT(*) +1062 +SELECT COUNT(*) FROM City WHERE Country LIKE 'C%'; +COUNT(*) +551 +SELECT COUNT(*) FROM City WHERE Country LIKE 'A%'; +COUNT(*) +107 +SELECT COUNT(*) FROM City WHERE Country BETWEEN 'S' AND 'Z'; +COUNT(*) +682 +EXPLAIN +SELECT * FROM City +WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Country,Population 4,3,4 NULL 5 Using sort_intersect(PRIMARY,Country,Population); Using where +EXPLAIN +SELECT * FROM City +WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country Population,Country 4,3 NULL 6 Using sort_intersect(Population,Country); Using where +EXPLAIN +SELECT * FROM City +WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country Country,PRIMARY 3,4 NULL 65 Using sort_intersect(Country,PRIMARY); Using where +EXPLAIN +SELECT * FROM City +WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000 +AND Country BETWEEN 'S' AND 'Z'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Population 4,4 NULL 44 Using sort_intersect(PRIMARY,Population); Using where +EXPLAIN +SELECT * FROM City +WHERE ID BETWEEN 1 AND 1000 AND Population > 700000 +AND Country BETWEEN 'S' AND 'Z' ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL 359 Using where +SELECT * FROM City USE INDEX () +WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%'; +ID Name Country Population +554 Santiago de Chile CHL 4703954 +SELECT * FROM City +WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%'; +ID Name Country Population +554 Santiago de Chile CHL 4703954 +SELECT * FROM City USE INDEX () +WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; +ID Name Country Population +SELECT * FROM City +WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; +ID Name Country Population +SELECT * FROM City USE INDEX () +WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%'; +ID Name Country Population +554 Santiago de Chile CHL 4703954 +555 Puente Alto CHL 386236 +556 Viña del Mar CHL 312493 +584 San José CRI 339131 +SELECT * FROM City +WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%'; +ID Name Country Population +554 Santiago de Chile CHL 4703954 +555 Puente Alto CHL 386236 +556 Viña del Mar CHL 312493 +584 San José CRI 339131 +SELECT * FROM City USE INDEX () +WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000 +AND Country BETWEEN 'S' AND 'Z'; +ID Name Country Population +3503 Toskent UZB 2117500 +3539 Caracas VEN 1975294 +3540 Maracaíbo VEN 1304776 +3541 Barquisimeto VEN 877239 +3542 Valencia VEN 794246 +3769 Ho Chi Minh City VNM 3980000 +3770 Hanoi VNM 1410000 +3771 Haiphong VNM 783133 +3793 New York USA 8008278 +3794 Los Angeles USA 3694820 +3795 Chicago USA 2896016 +3796 Houston USA 1953631 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3799 San Diego USA 1223400 +3800 Dallas USA 1188580 +3801 San Antonio USA 1144646 +3802 Detroit USA 951270 +3803 San Jose USA 894943 +3804 Indianapolis USA 791926 +3805 San Francisco USA 776733 +3806 Jacksonville USA 735167 +3807 Columbus USA 711470 +SELECT * FROM City +WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000 +AND Country BETWEEN 'S' AND 'Z'; +ID Name Country Population +3503 Toskent UZB 2117500 +3539 Caracas VEN 1975294 +3540 Maracaíbo VEN 1304776 +3541 Barquisimeto VEN 877239 +3542 Valencia VEN 794246 +3769 Ho Chi Minh City VNM 3980000 +3770 Hanoi VNM 1410000 +3771 Haiphong VNM 783133 +3793 New York USA 8008278 +3794 Los Angeles USA 3694820 +3795 Chicago USA 2896016 +3796 Houston USA 1953631 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3799 San Diego USA 1223400 +3800 Dallas USA 1188580 +3801 San Antonio USA 1144646 +3802 Detroit USA 951270 +3803 San Jose USA 894943 +3804 Indianapolis USA 791926 +3805 San Francisco USA 776733 +3806 Jacksonville USA 735167 +3807 Columbus USA 711470 +SELECT * FROM City USE INDEX () +WHERE ID BETWEEN 1 AND 1000 AND Population > 700000 +AND Country BETWEEN 'S' AND 'Z' ; +ID Name Country Population +SELECT * FROM City +WHERE ID BETWEEN 1 AND 1000 AND Population > 700000 +AND Country BETWEEN 'S' AND 'Z' ; +ID Name Country Population +SET SESSION sort_buffer_size = 2048; +EXPLAIN +SELECT * FROM City WHERE +Name LIKE 'C%' AND Population > 1000000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Name Name,Population 35,4 NULL 9 Using sort_intersect(Name,Population); Using where +EXPLAIN +SELECT * FROM City WHERE +Name LIKE 'M%' AND Population > 500000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Name Name 35 NULL 164 Using where +EXPLAIN +SELECT * FROM City +WHERE Name LIKE 'C%' AND Population > 1000000 AND Country LIKE 'C%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Country,Name Name,Population 35,4 NULL 9 Using sort_intersect(Name,Population); Using where +EXPLAIN +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Country,Name Name 35 NULL 225 Using where +EXPLAIN +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Country,Name Name 35 NULL 225 Using where +EXPLAIN +SELECT * FROM City +WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country Country,Population 3,4 NULL 6 Using sort_intersect(Country,Population); Using where +EXPLAIN +SELECT * FROM City +WHERE ID < 1000 AND Population > 700000 AND Country LIKE 'C%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL 359 Using where +SELECT * FROM City WHERE +Name LIKE 'C%' AND Population > 1000000; +ID Name Country Population +71 Córdoba ARG 1157507 +151 Chittagong BGD 1392860 +212 Curitiba BRA 1584232 +608 Cairo EGY 6789479 +712 Cape Town ZAF 2352121 +926 Conakry GIN 1090610 +1026 Calcutta [Kolkata] IND 4399819 +1027 Chennai (Madras) IND 3841396 +1892 Chongqing CHN 6351600 +1898 Chengdu CHN 3361500 +1900 Changchun CHN 2812000 +1910 Changsha CHN 1809800 +2258 Cali COL 2077386 +2485 Casablanca MAR 2940623 +2515 Ciudad de México MEX 8591309 +3539 Caracas VEN 1975294 +3795 Chicago USA 2896016 +SELECT * FROM City WHERE +Name LIKE 'M%' AND Population > 500000; +ID Name Country Population +223 Maceió BRA 786288 +653 Madrid ESP 2879052 +1042 Madurai IND 977856 +658 Málaga ESP 530553 +947 Malang IDN 716862 +2734 Managua NIC 959000 +215 Manaus BRA 1255049 +2711 Mandalay MMR 885300 +766 Manila PHL 1581082 +2698 Maputo MOZ 1018938 +77 Mar del Plata ARG 512880 +3540 Maracaíbo VEN 1304776 +2487 Marrakech MAR 621914 +2975 Marseille FRA 798430 +1381 Mashhad IRN 1887405 +2300 Mbuji-Mayi COD 806475 +942 Medan IDN 1843919 +2259 Medellín COL 1861265 +3176 Medina SAU 608300 +1051 Meerut IND 753778 +3175 Mekka SAU 965700 +131 Melbourne AUS 2865329 +3810 Memphis USA 650100 +2530 Mérida MEX 703324 +3364 Mersin (Içel) TUR 587212 +2526 Mexicali MEX 764902 +1465 Milano ITA 1300977 +3811 Milwaukee USA 596974 +3520 Minsk BLR 1674000 +1816 Mississauga CAN 608072 +3214 Mogadishu SOM 997000 +2440 Monrovia LBR 850000 +2523 Monterrey MEX 1108499 +3492 Montevideo URY 1236000 +1810 Montréal CAN 1016376 +2537 Morelia MEX 619958 +3580 Moscow RUS 8389200 +1366 Mosul IRQ 879000 +1945 Mudanjiang CHN 570000 +2826 Multan PAK 1182441 +1024 Mumbai (Bombay) IND 10500000 +3070 Munich [München] DEU 1194560 +3434 Mykolajiv UKR 508000 +SELECT * FROM City +WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; +ID Name Country Population +2259 Medellín COL 1861265 +1810 Montréal CAN 1016376 +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; +ID Name Country Population +2516 Guadalajara MEX 1647720 +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; +ID Name Country Population +1914 Guiyang CHN 1465200 +1928 Handan CHN 840000 +1905 Hangzhou CHN 2190500 +1895 Harbin CHN 4289800 +1916 Hefei CHN 1369100 +1950 Hegang CHN 520000 +1927 Hohhot CHN 916700 +1937 Huainan CHN 700000 +SELECT * FROM City +WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; +ID Name Country Population +SELECT * FROM City +WHERE ID < 1000 AND Population > 700000 AND Country LIKE 'C%'; +ID Name Country Population +554 Santiago de Chile CHL 4703954 +SET SESSION sort_buffer_size = default; +DROP INDEX Country ON City; +CREATE INDEX CountryID ON City(Country,ID); +CREATE INDEX CountryName ON City(Country,Name); +EXPLAIN +SELECT * FROM City +WHERE Country LIKE 'M%' AND Population > 700000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,CountryID,CountryName Population,CountryID 4,3 NULL 23 Using sort_intersect(Population,CountryID); Using where +EXPLAIN +SELECT * FROM City +WHERE Country='CHN' AND Population > 1000000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,CountryID,CountryName CountryID,Population 3,4 NULL 20 Using sort_intersect(CountryID,Population); Using where +EXPLAIN +SELECT * FROM City +WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Name,CountryID,CountryName CountryName 38 NULL 13 Using where +SELECT * FROM City USE INDEX () +WHERE Country LIKE 'M%' AND Population > 700000; +ID Name Country Population +2464 Kuala Lumpur MYS 1297526 +2482 Bamako MLI 809552 +2485 Casablanca MAR 2940623 +2515 Ciudad de México MEX 8591309 +2516 Guadalajara MEX 1647720 +2517 Ecatepec de Morelos MEX 1620303 +2518 Puebla MEX 1346176 +2519 Nezahualcóyotl MEX 1224924 +2520 Juárez MEX 1217818 +2521 Tijuana MEX 1212232 +2522 León MEX 1133576 +2523 Monterrey MEX 1108499 +2524 Zapopan MEX 1002239 +2525 Naucalpan de Juárez MEX 857511 +2526 Mexicali MEX 764902 +2527 Culiacán MEX 744859 +2528 Acapulco de Juárez MEX 721011 +2529 Tlalnepantla de Baz MEX 720755 +2530 Mérida MEX 703324 +2690 Chisinau MDA 719900 +2696 Ulan Bator MNG 773700 +2698 Maputo MOZ 1018938 +2710 Rangoon (Yangon) MMR 3361700 +2711 Mandalay MMR 885300 +SELECT * FROM City +WHERE Country LIKE 'M%' AND Population > 700000; +ID Name Country Population +2464 Kuala Lumpur MYS 1297526 +2482 Bamako MLI 809552 +2485 Casablanca MAR 2940623 +2515 Ciudad de México MEX 8591309 +2516 Guadalajara MEX 1647720 +2517 Ecatepec de Morelos MEX 1620303 +2518 Puebla MEX 1346176 +2519 Nezahualcóyotl MEX 1224924 +2520 Juárez MEX 1217818 +2521 Tijuana MEX 1212232 +2522 León MEX 1133576 +2523 Monterrey MEX 1108499 +2524 Zapopan MEX 1002239 +2525 Naucalpan de Juárez MEX 857511 +2526 Mexicali MEX 764902 +2527 Culiacán MEX 744859 +2528 Acapulco de Juárez MEX 721011 +2529 Tlalnepantla de Baz MEX 720755 +2530 Mérida MEX 703324 +2690 Chisinau MDA 719900 +2696 Ulan Bator MNG 773700 +2698 Maputo MOZ 1018938 +2710 Rangoon (Yangon) MMR 3361700 +2711 Mandalay MMR 885300 +SELECT * FROM City USE INDEX () +WHERE Country='CHN' AND Population > 1000000; +ID Name Country Population +1890 Shanghai CHN 9696300 +1891 Peking CHN 7472000 +1892 Chongqing CHN 6351600 +1893 Tianjin CHN 5286800 +1894 Wuhan CHN 4344600 +1895 Harbin CHN 4289800 +1896 Shenyang CHN 4265200 +1897 Kanton [Guangzhou] CHN 4256300 +1898 Chengdu CHN 3361500 +1899 Nanking [Nanjing] CHN 2870300 +1900 Changchun CHN 2812000 +1901 Xi´an CHN 2761400 +1902 Dalian CHN 2697000 +1903 Qingdao CHN 2596000 +1904 Jinan CHN 2278100 +1905 Hangzhou CHN 2190500 +1906 Zhengzhou CHN 2107200 +1907 Shijiazhuang CHN 2041500 +1908 Taiyuan CHN 1968400 +1909 Kunming CHN 1829500 +1910 Changsha CHN 1809800 +1911 Nanchang CHN 1691600 +1912 Fuzhou CHN 1593800 +1913 Lanzhou CHN 1565800 +1914 Guiyang CHN 1465200 +1915 Ningbo CHN 1371200 +1916 Hefei CHN 1369100 +1917 Urumt?i [Ürümqi] CHN 1310100 +1918 Anshan CHN 1200000 +1919 Fushun CHN 1200000 +1920 Nanning CHN 1161800 +1921 Zibo CHN 1140000 +1922 Qiqihar CHN 1070000 +1923 Jilin CHN 1040000 +1924 Tangshan CHN 1040000 +SELECT * FROM City +WHERE Country='CHN' AND Population > 1000000; +ID Name Country Population +1890 Shanghai CHN 9696300 +1891 Peking CHN 7472000 +1892 Chongqing CHN 6351600 +1893 Tianjin CHN 5286800 +1894 Wuhan CHN 4344600 +1895 Harbin CHN 4289800 +1896 Shenyang CHN 4265200 +1897 Kanton [Guangzhou] CHN 4256300 +1898 Chengdu CHN 3361500 +1899 Nanking [Nanjing] CHN 2870300 +1900 Changchun CHN 2812000 +1901 Xi´an CHN 2761400 +1902 Dalian CHN 2697000 +1903 Qingdao CHN 2596000 +1904 Jinan CHN 2278100 +1905 Hangzhou CHN 2190500 +1906 Zhengzhou CHN 2107200 +1907 Shijiazhuang CHN 2041500 +1908 Taiyuan CHN 1968400 +1909 Kunming CHN 1829500 +1910 Changsha CHN 1809800 +1911 Nanchang CHN 1691600 +1912 Fuzhou CHN 1593800 +1913 Lanzhou CHN 1565800 +1914 Guiyang CHN 1465200 +1915 Ningbo CHN 1371200 +1916 Hefei CHN 1369100 +1917 Urumt?i [Ürümqi] CHN 1310100 +1918 Anshan CHN 1200000 +1919 Fushun CHN 1200000 +1920 Nanning CHN 1161800 +1921 Zibo CHN 1140000 +1922 Qiqihar CHN 1070000 +1923 Jilin CHN 1040000 +1924 Tangshan CHN 1040000 +SELECT * FROM City USE INDEX () +WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%'; +ID Name Country Population +1892 Chongqing CHN 6351600 +1898 Chengdu CHN 3361500 +1900 Changchun CHN 2812000 +1910 Changsha CHN 1809800 +SELECT * FROM City +WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%'; +ID Name Country Population +1900 Changchun CHN 2812000 +1910 Changsha CHN 1809800 +1898 Chengdu CHN 3361500 +1892 Chongqing CHN 6351600 +DROP DATABASE world; +use test; +SET SESSION optimizer_switch='index_merge_sort_intersection=on'; diff --git a/mysql-test/r/index_intersect_innodb.result b/mysql-test/r/index_intersect_innodb.result new file mode 100644 index 00000000000..89c2e9faee9 --- /dev/null +++ b/mysql-test/r/index_intersect_innodb.result @@ -0,0 +1,923 @@ +SET SESSION STORAGE_ENGINE='InnoDB'; +DROP TABLE IF EXISTS t1,t2,t3,t4; +DROP DATABASE IF EXISTS world; +set names utf8; +CREATE DATABASE world; +use world; +CREATE TABLE Country ( +Code char(3) NOT NULL default '', +Name char(52) NOT NULL default '', +SurfaceArea float(10,2) NOT NULL default '0.00', +Population int(11) NOT NULL default '0', +Capital int(11) default NULL, +PRIMARY KEY (Code), +UNIQUE INDEX (Name) +); +CREATE TABLE City ( +ID int(11) NOT NULL auto_increment, +Name char(35) NOT NULL default '', +Country char(3) NOT NULL default '', +Population int(11) NOT NULL default '0', +PRIMARY KEY (ID), +INDEX (Population), +INDEX (Country) +); +CREATE TABLE CountryLanguage ( +Country char(3) NOT NULL default '', +Language char(30) NOT NULL default '', +Percentage float(3,1) NOT NULL default '0.0', +PRIMARY KEY (Country, Language), +INDEX (Percentage) +); +SELECT COUNT(*) FROM Country; +COUNT(*) +239 +SELECT COUNT(*) FROM City; +COUNT(*) +4079 +SELECT COUNT(*) FROM CountryLanguage; +COUNT(*) +984 +CREATE INDEX Name ON City(Name); +SET SESSION optimizer_switch='index_merge_sort_intersection=on'; +SELECT COUNT(*) FROM City; +COUNT(*) +4079 +SELECT COUNT(*) FROM City WHERE Name LIKE 'C%'; +COUNT(*) +281 +SELECT COUNT(*) FROM City WHERE Name LIKE 'M%'; +COUNT(*) +301 +SELECT COUNT(*) FROM City WHERE Population > 1000000; +COUNT(*) +237 +SELECT COUNT(*) FROM City WHERE Population > 500000; +COUNT(*) +539 +SELECT COUNT(*) FROM City WHERE Population > 300000; +COUNT(*) +1062 +SELECT COUNT(*) FROM City WHERE Population > 5000000; +COUNT(*) +24 +EXPLAIN +SELECT * FROM City WHERE +Name LIKE 'C%' AND Population > 1000000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Name Name,Population 35,4 NULL 16 Using sort_intersect(Name,Population); Using where +EXPLAIN +SELECT * FROM City WHERE +Name LIKE 'M%' AND Population > 500000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Name Population,Name 4,35 NULL 40 Using sort_intersect(Population,Name); Using where +EXPLAIN +SELECT * FROM City +WHERE Name LIKE 'M%' AND Population > 300000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Name Population,Name 4,35 NULL 79 Using sort_intersect(Population,Name); Using where +EXPLAIN +SELECT * FROM City +WHERE Name LIKE 'M%' AND Population > 5000000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Name Population,Name 4,35 NULL 1 Using sort_intersect(Population,Name); Using where +SELECT * FROM City USE INDEX () +WHERE Name LIKE 'C%' AND Population > 1000000; +ID Name Country Population +71 Córdoba ARG 1157507 +151 Chittagong BGD 1392860 +212 Curitiba BRA 1584232 +608 Cairo EGY 6789479 +712 Cape Town ZAF 2352121 +926 Conakry GIN 1090610 +1026 Calcutta [Kolkata] IND 4399819 +1027 Chennai (Madras) IND 3841396 +1892 Chongqing CHN 6351600 +1898 Chengdu CHN 3361500 +1900 Changchun CHN 2812000 +1910 Changsha CHN 1809800 +2258 Cali COL 2077386 +2485 Casablanca MAR 2940623 +2515 Ciudad de México MEX 8591309 +3539 Caracas VEN 1975294 +3795 Chicago USA 2896016 +SELECT * FROM City +WHERE Name LIKE 'C%' AND Population > 1000000; +ID Name Country Population +71 Córdoba ARG 1157507 +151 Chittagong BGD 1392860 +212 Curitiba BRA 1584232 +608 Cairo EGY 6789479 +712 Cape Town ZAF 2352121 +926 Conakry GIN 1090610 +1026 Calcutta [Kolkata] IND 4399819 +1027 Chennai (Madras) IND 3841396 +1892 Chongqing CHN 6351600 +1898 Chengdu CHN 3361500 +1900 Changchun CHN 2812000 +1910 Changsha CHN 1809800 +2258 Cali COL 2077386 +2485 Casablanca MAR 2940623 +2515 Ciudad de México MEX 8591309 +3539 Caracas VEN 1975294 +3795 Chicago USA 2896016 +SELECT * FROM City USE INDEX () +WHERE Name LIKE 'M%' AND Population > 500000; +ID Name Country Population +77 Mar del Plata ARG 512880 +131 Melbourne AUS 2865329 +215 Manaus BRA 1255049 +223 Maceió BRA 786288 +653 Madrid ESP 2879052 +658 Málaga ESP 530553 +766 Manila PHL 1581082 +942 Medan IDN 1843919 +947 Malang IDN 716862 +1024 Mumbai (Bombay) IND 10500000 +1042 Madurai IND 977856 +1051 Meerut IND 753778 +1366 Mosul IRQ 879000 +1381 Mashhad IRN 1887405 +1465 Milano ITA 1300977 +1810 Montréal CAN 1016376 +1816 Mississauga CAN 608072 +1945 Mudanjiang CHN 570000 +2259 Medellín COL 1861265 +2300 Mbuji-Mayi COD 806475 +2440 Monrovia LBR 850000 +2487 Marrakech MAR 621914 +2523 Monterrey MEX 1108499 +2526 Mexicali MEX 764902 +2530 Mérida MEX 703324 +2537 Morelia MEX 619958 +2698 Maputo MOZ 1018938 +2711 Mandalay MMR 885300 +2734 Managua NIC 959000 +2826 Multan PAK 1182441 +2975 Marseille FRA 798430 +3070 Munich [München] DEU 1194560 +3175 Mekka SAU 965700 +3176 Medina SAU 608300 +3214 Mogadishu SOM 997000 +3364 Mersin (Içel) TUR 587212 +3434 Mykolajiv UKR 508000 +3492 Montevideo URY 1236000 +3520 Minsk BLR 1674000 +3540 Maracaíbo VEN 1304776 +3580 Moscow RUS 8389200 +3810 Memphis USA 650100 +3811 Milwaukee USA 596974 +SELECT * FROM City +WHERE Name LIKE 'M%' AND Population > 500000; +ID Name Country Population +77 Mar del Plata ARG 512880 +131 Melbourne AUS 2865329 +215 Manaus BRA 1255049 +223 Maceió BRA 786288 +653 Madrid ESP 2879052 +658 Málaga ESP 530553 +766 Manila PHL 1581082 +942 Medan IDN 1843919 +947 Malang IDN 716862 +1024 Mumbai (Bombay) IND 10500000 +1042 Madurai IND 977856 +1051 Meerut IND 753778 +1366 Mosul IRQ 879000 +1381 Mashhad IRN 1887405 +1465 Milano ITA 1300977 +1810 Montréal CAN 1016376 +1816 Mississauga CAN 608072 +1945 Mudanjiang CHN 570000 +2259 Medellín COL 1861265 +2300 Mbuji-Mayi COD 806475 +2440 Monrovia LBR 850000 +2487 Marrakech MAR 621914 +2523 Monterrey MEX 1108499 +2526 Mexicali MEX 764902 +2530 Mérida MEX 703324 +2537 Morelia MEX 619958 +2698 Maputo MOZ 1018938 +2711 Mandalay MMR 885300 +2734 Managua NIC 959000 +2826 Multan PAK 1182441 +2975 Marseille FRA 798430 +3070 Munich [München] DEU 1194560 +3175 Mekka SAU 965700 +3176 Medina SAU 608300 +3214 Mogadishu SOM 997000 +3364 Mersin (Içel) TUR 587212 +3434 Mykolajiv UKR 508000 +3492 Montevideo URY 1236000 +3520 Minsk BLR 1674000 +3540 Maracaíbo VEN 1304776 +3580 Moscow RUS 8389200 +3810 Memphis USA 650100 +3811 Milwaukee USA 596974 +SELECT * FROM City USE INDEX () +WHERE Name LIKE 'M%' AND Population > 300000; +ID Name Country Population +77 Mar del Plata ARG 512880 +80 Merlo ARG 463846 +83 Moreno ARG 356993 +87 Morón ARG 349246 +131 Melbourne AUS 2865329 +215 Manaus BRA 1255049 +223 Maceió BRA 786288 +250 Mauá BRA 375055 +256 Moji das Cruzes BRA 339194 +462 Manchester GBR 430000 +653 Madrid ESP 2879052 +658 Málaga ESP 530553 +661 Murcia ESP 353504 +766 Manila PHL 1581082 +778 Makati PHL 444867 +781 Marikina PHL 391170 +783 Muntinlupa PHL 379310 +786 Malabon PHL 338855 +942 Medan IDN 1843919 +947 Malang IDN 716862 +962 Manado IDN 332288 +963 Mataram IDN 306600 +1024 Mumbai (Bombay) IND 10500000 +1042 Madurai IND 977856 +1051 Meerut IND 753778 +1074 Mysore IND 480692 +1081 Moradabad IND 429214 +1098 Malegaon IND 342595 +1366 Mosul IRQ 879000 +1381 Mashhad IRN 1887405 +1465 Milano ITA 1300977 +1559 Matsuyama JPN 466133 +1560 Matsudo JPN 461126 +1578 Machida JPN 364197 +1595 Miyazaki JPN 303784 +1810 Montréal CAN 1016376 +1816 Mississauga CAN 608072 +1882 Mombasa KEN 461753 +1945 Mudanjiang CHN 570000 +2005 Ma´anshan CHN 305421 +2259 Medellín COL 1861265 +2267 Manizales COL 337580 +2300 Mbuji-Mayi COD 806475 +2348 Masan KOR 441242 +2440 Monrovia LBR 850000 +2454 Macao MAC 437500 +2487 Marrakech MAR 621914 +2491 Meknès MAR 460000 +2523 Monterrey MEX 1108499 +2526 Mexicali MEX 764902 +2530 Mérida MEX 703324 +2537 Morelia MEX 619958 +2554 Matamoros MEX 416428 +2557 Mazatlán MEX 380265 +2698 Maputo MOZ 1018938 +2699 Matola MOZ 424662 +2711 Mandalay MMR 885300 +2712 Moulmein (Mawlamyine) MMR 307900 +2734 Managua NIC 959000 +2756 Mushin NGA 333200 +2757 Maiduguri NGA 320000 +2826 Multan PAK 1182441 +2975 Marseille FRA 798430 +3070 Munich [München] DEU 1194560 +3086 Mannheim DEU 307730 +3175 Mekka SAU 965700 +3176 Medina SAU 608300 +3214 Mogadishu SOM 997000 +3364 Mersin (Içel) TUR 587212 +3371 Malatya TUR 330312 +3434 Mykolajiv UKR 508000 +3435 Mariupol UKR 490000 +3438 Makijivka UKR 384000 +3492 Montevideo URY 1236000 +3520 Minsk BLR 1674000 +3522 Mogiljov BLR 356000 +3540 Maracaíbo VEN 1304776 +3545 Maracay VEN 444443 +3547 Maturín VEN 319726 +3580 Moscow RUS 8389200 +3622 Magnitogorsk RUS 427900 +3625 Murmansk RUS 376300 +3636 Mahat?kala RUS 332800 +3810 Memphis USA 650100 +3811 Milwaukee USA 596974 +3834 Mesa USA 396375 +3837 Minneapolis USA 382618 +3839 Miami USA 362470 +SELECT * FROM City +WHERE Name LIKE 'M%' AND Population > 300000; +ID Name Country Population +77 Mar del Plata ARG 512880 +80 Merlo ARG 463846 +83 Moreno ARG 356993 +87 Morón ARG 349246 +131 Melbourne AUS 2865329 +215 Manaus BRA 1255049 +223 Maceió BRA 786288 +250 Mauá BRA 375055 +256 Moji das Cruzes BRA 339194 +462 Manchester GBR 430000 +653 Madrid ESP 2879052 +658 Málaga ESP 530553 +661 Murcia ESP 353504 +766 Manila PHL 1581082 +778 Makati PHL 444867 +781 Marikina PHL 391170 +783 Muntinlupa PHL 379310 +786 Malabon PHL 338855 +942 Medan IDN 1843919 +947 Malang IDN 716862 +962 Manado IDN 332288 +963 Mataram IDN 306600 +1024 Mumbai (Bombay) IND 10500000 +1042 Madurai IND 977856 +1051 Meerut IND 753778 +1074 Mysore IND 480692 +1081 Moradabad IND 429214 +1098 Malegaon IND 342595 +1366 Mosul IRQ 879000 +1381 Mashhad IRN 1887405 +1465 Milano ITA 1300977 +1559 Matsuyama JPN 466133 +1560 Matsudo JPN 461126 +1578 Machida JPN 364197 +1595 Miyazaki JPN 303784 +1810 Montréal CAN 1016376 +1816 Mississauga CAN 608072 +1882 Mombasa KEN 461753 +1945 Mudanjiang CHN 570000 +2005 Ma´anshan CHN 305421 +2259 Medellín COL 1861265 +2267 Manizales COL 337580 +2300 Mbuji-Mayi COD 806475 +2348 Masan KOR 441242 +2440 Monrovia LBR 850000 +2454 Macao MAC 437500 +2487 Marrakech MAR 621914 +2491 Meknès MAR 460000 +2523 Monterrey MEX 1108499 +2526 Mexicali MEX 764902 +2530 Mérida MEX 703324 +2537 Morelia MEX 619958 +2554 Matamoros MEX 416428 +2557 Mazatlán MEX 380265 +2698 Maputo MOZ 1018938 +2699 Matola MOZ 424662 +2711 Mandalay MMR 885300 +2712 Moulmein (Mawlamyine) MMR 307900 +2734 Managua NIC 959000 +2756 Mushin NGA 333200 +2757 Maiduguri NGA 320000 +2826 Multan PAK 1182441 +2975 Marseille FRA 798430 +3070 Munich [München] DEU 1194560 +3086 Mannheim DEU 307730 +3175 Mekka SAU 965700 +3176 Medina SAU 608300 +3214 Mogadishu SOM 997000 +3364 Mersin (Içel) TUR 587212 +3371 Malatya TUR 330312 +3434 Mykolajiv UKR 508000 +3435 Mariupol UKR 490000 +3438 Makijivka UKR 384000 +3492 Montevideo URY 1236000 +3520 Minsk BLR 1674000 +3522 Mogiljov BLR 356000 +3540 Maracaíbo VEN 1304776 +3545 Maracay VEN 444443 +3547 Maturín VEN 319726 +3580 Moscow RUS 8389200 +3622 Magnitogorsk RUS 427900 +3625 Murmansk RUS 376300 +3636 Mahat?kala RUS 332800 +3810 Memphis USA 650100 +3811 Milwaukee USA 596974 +3834 Mesa USA 396375 +3837 Minneapolis USA 382618 +3839 Miami USA 362470 +SELECT * FROM City USE INDEX () +WHERE Name LIKE 'M%' AND Population > 5000000; +ID Name Country Population +1024 Mumbai (Bombay) IND 10500000 +3580 Moscow RUS 8389200 +SELECT * FROM City +WHERE Name LIKE 'M%' AND Population > 5000000; +ID Name Country Population +1024 Mumbai (Bombay) IND 10500000 +3580 Moscow RUS 8389200 +SELECT COUNT(*) FROM City WHERE Name BETWEEN 'M' AND 'N'; +COUNT(*) +301 +SELECT COUNT(*) FROM City WHERE Name BETWEEN 'G' AND 'J'; +COUNT(*) +408 +SELECT COUNT(*) FROM City WHERE Population > 1000000; +COUNT(*) +237 +SELECT COUNT(*) FROM City WHERE Population > 700000; +COUNT(*) +358 +SELECT COUNT(*) FROM City WHERE Population > 500000; +COUNT(*) +539 +SELECT COUNT(*) FROM City WHERE Country LIKE 'C%'; +COUNT(*) +551 +SELECT COUNT(*) FROM City WHERE Country LIKE 'L%'; +COUNT(*) +29 +EXPLAIN +SELECT * FROM City +WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Country,Name Population,Name,Country 4,35,3 NULL 2 Using sort_intersect(Population,Name,Country); Using where +EXPLAIN +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'L%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Country,Name Country,Population 3,4 NULL 2 Using sort_intersect(Country,Population); Using where +EXPLAIN +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Country,Name Population,Country,Name 4,3,35 NULL 7 Using sort_intersect(Population,Country,Name); Using where +SELECT * FROM City USE INDEX () +WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; +ID Name Country Population +1810 Montréal CAN 1016376 +2259 Medellín COL 1861265 +SELECT * FROM City +WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; +ID Name Country Population +1810 Montréal CAN 1016376 +2259 Medellín COL 1861265 +SELECT * FROM City USE INDEX () +WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; +ID Name Country Population +2516 Guadalajara MEX 1647720 +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; +ID Name Country Population +2516 Guadalajara MEX 1647720 +SELECT * FROM City USE INDEX () +WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; +ID Name Country Population +1895 Harbin CHN 4289800 +1905 Hangzhou CHN 2190500 +1914 Guiyang CHN 1465200 +1916 Hefei CHN 1369100 +1927 Hohhot CHN 916700 +1928 Handan CHN 840000 +1937 Huainan CHN 700000 +1950 Hegang CHN 520000 +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; +ID Name Country Population +1895 Harbin CHN 4289800 +1905 Hangzhou CHN 2190500 +1914 Guiyang CHN 1465200 +1916 Hefei CHN 1369100 +1927 Hohhot CHN 916700 +1928 Handan CHN 840000 +1937 Huainan CHN 700000 +1950 Hegang CHN 520000 +SELECT COUNT(*) FROM City WHERE ID BETWEEN 500 AND 999; +COUNT(*) +500 +SELECT COUNT(*) FROM City WHERE ID BETWEEN 3500 AND 3999; +COUNT(*) +500 +SELECT COUNT(*) FROM City WHERE ID BETWEEN 1 AND 1000; +COUNT(*) +1000 +SELECT COUNT(*) FROM City WHERE Population > 700000; +COUNT(*) +358 +SELECT COUNT(*) FROM City WHERE Population > 1000000; +COUNT(*) +237 +SELECT COUNT(*) FROM City WHERE Population > 300000; +COUNT(*) +1062 +SELECT COUNT(*) FROM City WHERE Country LIKE 'C%'; +COUNT(*) +551 +SELECT COUNT(*) FROM City WHERE Country LIKE 'A%'; +COUNT(*) +107 +SELECT COUNT(*) FROM City WHERE Country BETWEEN 'S' AND 'Z'; +COUNT(*) +682 +EXPLAIN +SELECT * FROM City +WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Country,Population 4,3,4 NULL 11 Using sort_intersect(PRIMARY,Country,Population); Using where +EXPLAIN +SELECT * FROM City +WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Population,Country 4,4,3 NULL 1 Using sort_intersect(PRIMARY,Population,Country); Using where +EXPLAIN +SELECT * FROM City +WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Population,Country 4,4,3 NULL 34 Using sort_intersect(PRIMARY,Population,Country); Using where +EXPLAIN +SELECT * FROM City +WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000 +AND Country BETWEEN 'S' AND 'Z'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Country,Population 4,3,4 NULL 12 Using sort_intersect(PRIMARY,Country,Population); Using where +EXPLAIN +SELECT * FROM City +WHERE ID BETWEEN 1 AND 1000 AND Population > 700000 +AND Country BETWEEN 'S' AND 'Z' ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Country,Population 4,3,4 NULL 21 Using sort_intersect(PRIMARY,Country,Population); Using where +SELECT * FROM City USE INDEX () +WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%'; +ID Name Country Population +554 Santiago de Chile CHL 4703954 +SELECT * FROM City +WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%'; +ID Name Country Population +554 Santiago de Chile CHL 4703954 +SELECT * FROM City USE INDEX () +WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; +ID Name Country Population +SELECT * FROM City +WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; +ID Name Country Population +SELECT * FROM City USE INDEX () +WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%'; +ID Name Country Population +554 Santiago de Chile CHL 4703954 +555 Puente Alto CHL 386236 +556 Viña del Mar CHL 312493 +584 San José CRI 339131 +SELECT * FROM City +WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%'; +ID Name Country Population +554 Santiago de Chile CHL 4703954 +555 Puente Alto CHL 386236 +556 Viña del Mar CHL 312493 +584 San José CRI 339131 +SELECT * FROM City USE INDEX () +WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000 +AND Country BETWEEN 'S' AND 'Z'; +ID Name Country Population +3503 Toskent UZB 2117500 +3539 Caracas VEN 1975294 +3540 Maracaíbo VEN 1304776 +3541 Barquisimeto VEN 877239 +3542 Valencia VEN 794246 +3769 Ho Chi Minh City VNM 3980000 +3770 Hanoi VNM 1410000 +3771 Haiphong VNM 783133 +3793 New York USA 8008278 +3794 Los Angeles USA 3694820 +3795 Chicago USA 2896016 +3796 Houston USA 1953631 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3799 San Diego USA 1223400 +3800 Dallas USA 1188580 +3801 San Antonio USA 1144646 +3802 Detroit USA 951270 +3803 San Jose USA 894943 +3804 Indianapolis USA 791926 +3805 San Francisco USA 776733 +3806 Jacksonville USA 735167 +3807 Columbus USA 711470 +SELECT * FROM City +WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000 +AND Country BETWEEN 'S' AND 'Z'; +ID Name Country Population +3503 Toskent UZB 2117500 +3539 Caracas VEN 1975294 +3540 Maracaíbo VEN 1304776 +3541 Barquisimeto VEN 877239 +3542 Valencia VEN 794246 +3769 Ho Chi Minh City VNM 3980000 +3770 Hanoi VNM 1410000 +3771 Haiphong VNM 783133 +3793 New York USA 8008278 +3794 Los Angeles USA 3694820 +3795 Chicago USA 2896016 +3796 Houston USA 1953631 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3799 San Diego USA 1223400 +3800 Dallas USA 1188580 +3801 San Antonio USA 1144646 +3802 Detroit USA 951270 +3803 San Jose USA 894943 +3804 Indianapolis USA 791926 +3805 San Francisco USA 776733 +3806 Jacksonville USA 735167 +3807 Columbus USA 711470 +SELECT * FROM City USE INDEX () +WHERE ID BETWEEN 1 AND 1000 AND Population > 700000 +AND Country BETWEEN 'S' AND 'Z' ; +ID Name Country Population +SELECT * FROM City +WHERE ID BETWEEN 1 AND 1000 AND Population > 700000 +AND Country BETWEEN 'S' AND 'Z' ; +ID Name Country Population +SET SESSION sort_buffer_size = 2048; +EXPLAIN +SELECT * FROM City WHERE +Name LIKE 'C%' AND Population > 1000000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Name Population,Name 4,35 NULL 16 Using sort_intersect(Population,Name); Using where +EXPLAIN +SELECT * FROM City WHERE +Name LIKE 'M%' AND Population > 500000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Name Name,Population 35,4 NULL 40 Using sort_intersect(Name,Population); Using where +EXPLAIN +SELECT * FROM City +WHERE Name LIKE 'C%' AND Population > 1000000 AND Country LIKE 'C%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Country,Name Population,Name 4,35 NULL 16 Using sort_intersect(Population,Name); Using where +EXPLAIN +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Country,Name Population,Name 4,35 NULL 36 Using sort_intersect(Population,Name); Using where +EXPLAIN +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Country,Name Name,Population,Country 35,4,3 NULL 7 Using sort_intersect(Name,Population,Country); Using where +EXPLAIN +SELECT * FROM City +WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Population,Country 4,4,3 NULL 1 Using sort_intersect(PRIMARY,Population,Country); Using where +EXPLAIN +SELECT * FROM City +WHERE ID < 1000 AND Population > 700000 AND Country LIKE 'C%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Country,Population 4,3,4 NULL 17 Using sort_intersect(PRIMARY,Country,Population); Using where +SELECT * FROM City WHERE +Name LIKE 'C%' AND Population > 1000000; +ID Name Country Population +71 Córdoba ARG 1157507 +151 Chittagong BGD 1392860 +212 Curitiba BRA 1584232 +608 Cairo EGY 6789479 +712 Cape Town ZAF 2352121 +926 Conakry GIN 1090610 +1026 Calcutta [Kolkata] IND 4399819 +1027 Chennai (Madras) IND 3841396 +1892 Chongqing CHN 6351600 +1898 Chengdu CHN 3361500 +1900 Changchun CHN 2812000 +1910 Changsha CHN 1809800 +2258 Cali COL 2077386 +2485 Casablanca MAR 2940623 +2515 Ciudad de México MEX 8591309 +3539 Caracas VEN 1975294 +3795 Chicago USA 2896016 +SELECT * FROM City WHERE +Name LIKE 'M%' AND Population > 500000; +ID Name Country Population +77 Mar del Plata ARG 512880 +131 Melbourne AUS 2865329 +215 Manaus BRA 1255049 +223 Maceió BRA 786288 +653 Madrid ESP 2879052 +658 Málaga ESP 530553 +766 Manila PHL 1581082 +942 Medan IDN 1843919 +947 Malang IDN 716862 +1024 Mumbai (Bombay) IND 10500000 +1042 Madurai IND 977856 +1051 Meerut IND 753778 +1366 Mosul IRQ 879000 +1381 Mashhad IRN 1887405 +1465 Milano ITA 1300977 +1810 Montréal CAN 1016376 +1816 Mississauga CAN 608072 +1945 Mudanjiang CHN 570000 +2259 Medellín COL 1861265 +2300 Mbuji-Mayi COD 806475 +2440 Monrovia LBR 850000 +2487 Marrakech MAR 621914 +2523 Monterrey MEX 1108499 +2526 Mexicali MEX 764902 +2530 Mérida MEX 703324 +2537 Morelia MEX 619958 +2698 Maputo MOZ 1018938 +2711 Mandalay MMR 885300 +2734 Managua NIC 959000 +2826 Multan PAK 1182441 +2975 Marseille FRA 798430 +3070 Munich [München] DEU 1194560 +3175 Mekka SAU 965700 +3176 Medina SAU 608300 +3214 Mogadishu SOM 997000 +3364 Mersin (Içel) TUR 587212 +3434 Mykolajiv UKR 508000 +3492 Montevideo URY 1236000 +3520 Minsk BLR 1674000 +3540 Maracaíbo VEN 1304776 +3580 Moscow RUS 8389200 +3810 Memphis USA 650100 +3811 Milwaukee USA 596974 +SELECT * FROM City +WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; +ID Name Country Population +1810 Montréal CAN 1016376 +2259 Medellín COL 1861265 +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; +ID Name Country Population +2516 Guadalajara MEX 1647720 +SELECT * FROM City +WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; +ID Name Country Population +1895 Harbin CHN 4289800 +1905 Hangzhou CHN 2190500 +1914 Guiyang CHN 1465200 +1916 Hefei CHN 1369100 +1927 Hohhot CHN 916700 +1928 Handan CHN 840000 +1937 Huainan CHN 700000 +1950 Hegang CHN 520000 +SELECT * FROM City +WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; +ID Name Country Population +SELECT * FROM City +WHERE ID < 1000 AND Population > 700000 AND Country LIKE 'C%'; +ID Name Country Population +554 Santiago de Chile CHL 4703954 +SET SESSION sort_buffer_size = default; +DROP INDEX Country ON City; +CREATE INDEX CountryID ON City(Country,ID); +CREATE INDEX CountryName ON City(Country,Name); +EXPLAIN +SELECT * FROM City +WHERE Country LIKE 'M%' AND Population > 700000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,CountryID,CountryName Population,CountryID 4,3 NULL 24 Using sort_intersect(Population,CountryID); Using where +EXPLAIN +SELECT * FROM City +WHERE Country='CHN' AND Population > 1000000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,CountryID,CountryName CountryID,Population 3,4 NULL 21 Using sort_intersect(CountryID,Population); Using where +EXPLAIN +SELECT * FROM City +WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range Population,Name,CountryID,CountryName CountryName,Population 38,4 NULL 1 Using sort_intersect(CountryName,Population); Using where +SELECT * FROM City USE INDEX () +WHERE Country LIKE 'M%' AND Population > 700000; +ID Name Country Population +2464 Kuala Lumpur MYS 1297526 +2482 Bamako MLI 809552 +2485 Casablanca MAR 2940623 +2515 Ciudad de México MEX 8591309 +2516 Guadalajara MEX 1647720 +2517 Ecatepec de Morelos MEX 1620303 +2518 Puebla MEX 1346176 +2519 Nezahualcóyotl MEX 1224924 +2520 Juárez MEX 1217818 +2521 Tijuana MEX 1212232 +2522 León MEX 1133576 +2523 Monterrey MEX 1108499 +2524 Zapopan MEX 1002239 +2525 Naucalpan de Juárez MEX 857511 +2526 Mexicali MEX 764902 +2527 Culiacán MEX 744859 +2528 Acapulco de Juárez MEX 721011 +2529 Tlalnepantla de Baz MEX 720755 +2530 Mérida MEX 703324 +2690 Chisinau MDA 719900 +2696 Ulan Bator MNG 773700 +2698 Maputo MOZ 1018938 +2710 Rangoon (Yangon) MMR 3361700 +2711 Mandalay MMR 885300 +SELECT * FROM City +WHERE Country LIKE 'M%' AND Population > 700000; +ID Name Country Population +2464 Kuala Lumpur MYS 1297526 +2482 Bamako MLI 809552 +2485 Casablanca MAR 2940623 +2515 Ciudad de México MEX 8591309 +2516 Guadalajara MEX 1647720 +2517 Ecatepec de Morelos MEX 1620303 +2518 Puebla MEX 1346176 +2519 Nezahualcóyotl MEX 1224924 +2520 Juárez MEX 1217818 +2521 Tijuana MEX 1212232 +2522 León MEX 1133576 +2523 Monterrey MEX 1108499 +2524 Zapopan MEX 1002239 +2525 Naucalpan de Juárez MEX 857511 +2526 Mexicali MEX 764902 +2527 Culiacán MEX 744859 +2528 Acapulco de Juárez MEX 721011 +2529 Tlalnepantla de Baz MEX 720755 +2530 Mérida MEX 703324 +2690 Chisinau MDA 719900 +2696 Ulan Bator MNG 773700 +2698 Maputo MOZ 1018938 +2710 Rangoon (Yangon) MMR 3361700 +2711 Mandalay MMR 885300 +SELECT * FROM City USE INDEX () +WHERE Country='CHN' AND Population > 1000000; +ID Name Country Population +1890 Shanghai CHN 9696300 +1891 Peking CHN 7472000 +1892 Chongqing CHN 6351600 +1893 Tianjin CHN 5286800 +1894 Wuhan CHN 4344600 +1895 Harbin CHN 4289800 +1896 Shenyang CHN 4265200 +1897 Kanton [Guangzhou] CHN 4256300 +1898 Chengdu CHN 3361500 +1899 Nanking [Nanjing] CHN 2870300 +1900 Changchun CHN 2812000 +1901 Xi´an CHN 2761400 +1902 Dalian CHN 2697000 +1903 Qingdao CHN 2596000 +1904 Jinan CHN 2278100 +1905 Hangzhou CHN 2190500 +1906 Zhengzhou CHN 2107200 +1907 Shijiazhuang CHN 2041500 +1908 Taiyuan CHN 1968400 +1909 Kunming CHN 1829500 +1910 Changsha CHN 1809800 +1911 Nanchang CHN 1691600 +1912 Fuzhou CHN 1593800 +1913 Lanzhou CHN 1565800 +1914 Guiyang CHN 1465200 +1915 Ningbo CHN 1371200 +1916 Hefei CHN 1369100 +1917 Urumt?i [Ürümqi] CHN 1310100 +1918 Anshan CHN 1200000 +1919 Fushun CHN 1200000 +1920 Nanning CHN 1161800 +1921 Zibo CHN 1140000 +1922 Qiqihar CHN 1070000 +1923 Jilin CHN 1040000 +1924 Tangshan CHN 1040000 +SELECT * FROM City +WHERE Country='CHN' AND Population > 1000000; +ID Name Country Population +1890 Shanghai CHN 9696300 +1891 Peking CHN 7472000 +1892 Chongqing CHN 6351600 +1893 Tianjin CHN 5286800 +1894 Wuhan CHN 4344600 +1895 Harbin CHN 4289800 +1896 Shenyang CHN 4265200 +1897 Kanton [Guangzhou] CHN 4256300 +1898 Chengdu CHN 3361500 +1899 Nanking [Nanjing] CHN 2870300 +1900 Changchun CHN 2812000 +1901 Xi´an CHN 2761400 +1902 Dalian CHN 2697000 +1903 Qingdao CHN 2596000 +1904 Jinan CHN 2278100 +1905 Hangzhou CHN 2190500 +1906 Zhengzhou CHN 2107200 +1907 Shijiazhuang CHN 2041500 +1908 Taiyuan CHN 1968400 +1909 Kunming CHN 1829500 +1910 Changsha CHN 1809800 +1911 Nanchang CHN 1691600 +1912 Fuzhou CHN 1593800 +1913 Lanzhou CHN 1565800 +1914 Guiyang CHN 1465200 +1915 Ningbo CHN 1371200 +1916 Hefei CHN 1369100 +1917 Urumt?i [Ürümqi] CHN 1310100 +1918 Anshan CHN 1200000 +1919 Fushun CHN 1200000 +1920 Nanning CHN 1161800 +1921 Zibo CHN 1140000 +1922 Qiqihar CHN 1070000 +1923 Jilin CHN 1040000 +1924 Tangshan CHN 1040000 +SELECT * FROM City USE INDEX () +WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%'; +ID Name Country Population +1892 Chongqing CHN 6351600 +1898 Chengdu CHN 3361500 +1900 Changchun CHN 2812000 +1910 Changsha CHN 1809800 +SELECT * FROM City +WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%'; +ID Name Country Population +1892 Chongqing CHN 6351600 +1898 Chengdu CHN 3361500 +1900 Changchun CHN 2812000 +1910 Changsha CHN 1809800 +DROP DATABASE world; +use test; +SET SESSION optimizer_switch='index_merge_sort_intersection=on'; +SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result index bd49af16105..feef9007995 100644 --- a/mysql-test/r/index_merge_innodb.result +++ b/mysql-test/r/index_merge_innodb.result @@ -1,3 +1,5 @@ +set @optimizer_switch_save= @@optimizer_switch; +set optimizer_switch='index_merge_sort_intersection=off'; #---------------- Index merge test 2 ------------------------------------------- SET SESSION STORAGE_ENGINE = InnoDB; drop table if exists t1,t2; @@ -636,3 +638,4 @@ WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; COUNT(*) 6145 DROP TABLE t1; +set optimizer_switch= @optimizer_switch_save; diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result index 0a017ff8c8a..91a1ec6b931 100644 --- a/mysql-test/r/index_merge_myisam.result +++ b/mysql-test/r/index_merge_myisam.result @@ -1,3 +1,5 @@ +set @optimizer_switch_save= @@optimizer_switch; +set optimizer_switch='index_merge_sort_intersection=off'; #---------------- Index merge test 1 ------------------------------------------- SET SESSION STORAGE_ENGINE = MyISAM; drop table if exists t0, t1, t2, t3, t4; @@ -205,10 +207,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index_merge i1_3,i2_3 i1_3,i2_3 4,4 NULL 2 Using sort_union(i1_3,i2_3); Using where explain select key3 from t2 where key1 <100 or key2 < 100; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 index i1_3,i2_3 i321 12 NULL 1024 Using where; Using index +1 SIMPLE t2 index_merge i1_3,i2_3 i1_3,i2_3 4,4 NULL 188 Using sort_union(i1_3,i2_3); Using where explain select key7 from t2 where key1 <100 or key2 < 100; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL i1_3,i2_3 NULL NULL NULL 1024 Using where +1 SIMPLE t2 index_merge i1_3,i2_3 i1_3,i2_3 4,4 NULL 188 Using sort_union(i1_3,i2_3); Using where create table t4 ( key1a int not null, key1b int not null, @@ -569,9 +571,7 @@ INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; -SET SESSION sort_buffer_size=1; -Warnings: -Warning 1292 Truncated incorrect sort_buffer_size value: '1' +SET SESSION sort_buffer_size=1024*8; EXPLAIN SELECT * FROM t1 FORCE INDEX(a,b) WHERE a LIKE 'a%' OR b LIKE 'b%' ORDER BY a,b; @@ -1421,19 +1421,19 @@ drop table t1; # select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off set optimizer_switch='index_merge=off,index_merge_union=off'; select @@optimizer_switch; @@optimizer_switch -index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on +index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off set optimizer_switch='index_merge_union=on'; select @@optimizer_switch; @@optimizer_switch -index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on +index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off set optimizer_switch='default,index_merge_sort_union=off'; select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on +index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=on set optimizer_switch=4; ERROR 42000: Variable 'optimizer_switch' can't be set to the value of '4' set optimizer_switch=NULL; @@ -1460,21 +1460,21 @@ set optimizer_switch=default; set optimizer_switch='index_merge=off,index_merge_union=off,default'; select @@optimizer_switch; @@optimizer_switch -index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on +index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on set optimizer_switch=default; select @@global.optimizer_switch; @@global.optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on set @@global.optimizer_switch=default; select @@global.optimizer_switch; @@global.optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on # # Check index_merge's @@optimizer_switch flags # select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on create table t0 (a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t1 (a int, b int, c int, filler char(100), @@ -1551,7 +1551,7 @@ explain select * from t1 where a=10 and b=10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref a,b a 5 const 49 Using where No intersect if it is disabled: -set optimizer_switch='default,index_merge_intersection=off'; +set optimizer_switch='default,index_merge_sort_intersection=off,index_merge_intersection=off'; explain select * from t1 where a=10 and b=10; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref a,b a 5 const 49 Using where @@ -1584,5 +1584,6 @@ id select_type table type possible_keys key key_len ref rows Extra set optimizer_switch=default; show variables like 'optimizer_switch'; Variable_name Value -optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on +optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on drop table t0, t1; +set optimizer_switch= @optimizer_switch_save; diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 6827fd0bc76..06cb2cb5620 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -1421,9 +1421,9 @@ DROP TABLE t1; # create table t1(a int, b tinytext); insert into t1 values (1,2),(3,2); -set session sort_buffer_size= 30000; +set session sort_buffer_size= 1000; Warnings: -Warning 1292 Truncated incorrect sort_buffer_size value: '30000' +Warning 1292 Truncated incorrect sort_buffer_size value: '1000' set session max_sort_length= 2180; select * from t1 order by b; ERROR HY001: Out of sort memory; increase server sort buffer size diff --git a/mysql-test/r/range_vs_index_merge.result b/mysql-test/r/range_vs_index_merge.result index 0f9c46f182d..b616afc9578 100644 --- a/mysql-test/r/range_vs_index_merge.result +++ b/mysql-test/r/range_vs_index_merge.result @@ -38,6 +38,7 @@ SELECT COUNT(*) FROM CountryLanguage; COUNT(*) 984 CREATE INDEX Name ON City(Name); +set session optimizer_switch='index_merge_sort_intersection=off'; EXPLAIN SELECT * FROM City WHERE (Population >= 100000 OR Name LIKE 'P%' OR Population < 100000); @@ -71,9 +72,9 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Population Population 4 NULL 459 Using where EXPLAIN SELECT * FROM City -WHERE (Population > 101000 AND Population < 103000); +WHERE (Population > 101000 AND Population < 102000); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population Population 4 NULL 81 Using where +1 SIMPLE City range Population Population 4 NULL 39 Using where EXPLAIN SELECT * FROM City WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')); @@ -88,9 +89,9 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) -AND (Population > 101000 AND Population < 103000); +AND (Population > 101000 AND Population < 102000); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Country,Name Population 4 NULL 81 Using where +1 SIMPLE City range Population,Country,Name Population 4 NULL 39 Using where SELECT * FROM City USE INDEX () WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) AND (Population > 101000 AND Population < 115000); @@ -153,24 +154,20 @@ ID Name Country Population 4032 Cambridge USA 101355 SELECT * FROM City USE INDEX () WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) -AND (Population > 101000 AND Population < 103000); +AND (Population > 101000 AND Population < 102000); ID Name Country Population 637 Mit Ghamr EGY 101801 707 Marbella ESP 101144 -3411 Ceyhan TUR 102412 3792 Tartu EST 101246 -4027 Cape Coral USA 102286 4032 Cambridge USA 101355 SELECT * FROM City WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) -AND (Population > 101000 AND Population < 103000); +AND (Population > 101000 AND Population < 102000); ID Name Country Population 707 Marbella ESP 101144 3792 Tartu EST 101246 4032 Cambridge USA 101355 637 Mit Ghamr EGY 101801 -4027 Cape Coral USA 102286 -3411 Ceyhan TUR 102412 EXPLAIN SELECT * FROM City WHERE (Name < 'Ac'); id select_type table type possible_keys key key_len ref rows Extra @@ -328,9 +325,9 @@ ID Name Country Population 1003 Pemalang IDN 103500 2663 Río Bravo MEX 103901 EXPLAIN -SELECT * FROM City WHERE (ID < 50) OR (ID BETWEEN 100 AND 110); +SELECT * FROM City WHERE (ID < 30) OR (ID BETWEEN 100 AND 150); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 61 Using where +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 81 Using where EXPLAIN SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 300 AND 600); id select_type table type possible_keys key key_len ref rows Extra @@ -353,11 +350,11 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Name Name 35 NULL 72 Using where EXPLAIN SELECT * FROM City -WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) +WHERE ((ID < 30) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 61 Using where +1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 41 Using where EXPLAIN SELECT * FROM City WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) @@ -373,7 +370,7 @@ OR ((ID BETWEEN 300 AND 600) AND id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,Population 35,3,4 NULL 128 Using sort_union(Name,Country,Population); Using where SELECT * FROM City USE INDEX () -WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) +WHERE ((ID < 30) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); ID Name Country Population @@ -384,13 +381,10 @@ ID Name Country Population 7 Haag NLD 440900 16 Haarlem NLD 148772 25 Haarlemmermeer NLD 110722 -31 Heerlen NLD 95052 -33 Willemstad ANT 2345 -34 Tirana ALB 270000 100 Paraná ARG 207041 102 Posadas ARG 201273 SELECT * FROM City -WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) +WHERE ((ID < 30) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); ID Name Country Population @@ -401,9 +395,6 @@ ID Name Country Population 7 Haag NLD 440900 16 Haarlem NLD 148772 25 Haarlemmermeer NLD 110722 -31 Heerlen NLD 95052 -33 Willemstad ANT 2345 -34 Tirana ALB 270000 100 Paraná ARG 207041 102 Posadas ARG 201273 SELECT * FROM City USE INDEX() @@ -726,119 +717,55 @@ SELECT * FROM City WHERE Name LIKE 'P%'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Name Name 35 NULL 135 Using where EXPLAIN -SELECT * FROM City WHERE (Population > 101000 AND Population < 103000); +SELECT * FROM City WHERE (Population > 101000 AND Population < 102000); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population Population 4 NULL 81 Using where +1 SIMPLE City range Population Population 4 NULL 39 Using where EXPLAIN SELECT * FROM City WHERE Country='USA'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City ref Country,CountryPopulation Country 3 const 267 Using where EXPLAIN SELECT * FROM City -WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') +WHERE ((Population > 101000 AND Population < 102000) OR Name LIKE 'Pas%') AND Country='USA'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge Population,Country,Name,CountryPopulation CountryPopulation,Name 7,35 NULL 15 Using sort_union(CountryPopulation,Name); Using where +1 SIMPLE City index_merge Population,Country,Name,CountryPopulation CountryPopulation,Name 7,35 NULL 8 Using sort_union(CountryPopulation,Name); Using where EXPLAIN SELECT * FROM City -WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') -AND Country='USA'; +WHERE ((Population > 101000 AND Population < 1000000) OR Name LIKE 'P%' ) +AND Country='USA' AND Name LIKE '%port'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City ref Population,Country,Name,CountryPopulation Country 3 const 267 Using where SELECT * FROM City -WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') +WHERE ((Population > 101000 AND Population < 102000) OR Name LIKE 'Pas%') AND Country='USA'; ID Name Country Population 3943 Pasadena USA 141674 3953 Pasadena USA 133936 -4023 Gary USA 102746 -4024 Berkeley USA 102743 -4025 Santa Clara USA 102361 -4026 Green Bay USA 102313 -4027 Cape Coral USA 102286 -4028 Arvada USA 102153 -4029 Pueblo USA 102121 4030 Sandy USA 101853 4031 Athens-Clarke County USA 101489 4032 Cambridge USA 101355 SELECT * FROM City USE INDEX () -WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') +WHERE ((Population > 101000 AND Population < 102000) OR Name LIKE 'Pas%') AND Country='USA'; ID Name Country Population 3943 Pasadena USA 141674 3953 Pasadena USA 133936 -4023 Gary USA 102746 -4024 Berkeley USA 102743 -4025 Santa Clara USA 102361 -4026 Green Bay USA 102313 -4027 Cape Coral USA 102286 -4028 Arvada USA 102153 -4029 Pueblo USA 102121 4030 Sandy USA 101853 4031 Athens-Clarke County USA 101489 4032 Cambridge USA 101355 SELECT * FROM City -WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') -AND Country='USA'; +WHERE ((Population > 101000 AND Population < 1000000) OR Name LIKE 'P%') +AND Country='USA' AND Name LIKE '%port'; ID Name Country Population -3797 Philadelphia USA 1517550 -3798 Phoenix USA 1321045 -3820 Portland USA 529121 -3844 Pittsburgh USA 334563 -3870 Plano USA 222030 -3912 Providence USA 173618 -3930 Pomona USA 149473 -3932 Paterson USA 149222 -3943 Pasadena USA 141674 -3951 Pembroke Pines USA 137427 -3953 Pasadena USA 133936 -3967 Paradise USA 124682 -3986 Palmdale USA 116670 -3996 Peoria USA 112936 -4007 Peoria USA 108364 -4016 Provo USA 105166 -4023 Gary USA 102746 -4024 Berkeley USA 102743 -4025 Santa Clara USA 102361 -4026 Green Bay USA 102313 -4027 Cape Coral USA 102286 -4028 Arvada USA 102153 -4029 Pueblo USA 102121 -4030 Sandy USA 101853 -4031 Athens-Clarke County USA 101489 -4032 Cambridge USA 101355 -4035 Portsmouth USA 100565 +3880 Shreveport USA 200145 +3946 Bridgeport USA 139529 SELECT * FROM City USE INDEX () -WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') -AND Country='USA'; +WHERE ((Population > 101000 AND Population < 1000000) OR Name LIKE 'P%') +AND Country='USA' AND Name LIKE '%port'; ID Name Country Population -3797 Philadelphia USA 1517550 -3798 Phoenix USA 1321045 -3820 Portland USA 529121 -3844 Pittsburgh USA 334563 -3870 Plano USA 222030 -3912 Providence USA 173618 -3930 Pomona USA 149473 -3932 Paterson USA 149222 -3943 Pasadena USA 141674 -3951 Pembroke Pines USA 137427 -3953 Pasadena USA 133936 -3967 Paradise USA 124682 -3986 Palmdale USA 116670 -3996 Peoria USA 112936 -4007 Peoria USA 108364 -4016 Provo USA 105166 -4023 Gary USA 102746 -4024 Berkeley USA 102743 -4025 Santa Clara USA 102361 -4026 Green Bay USA 102313 -4027 Cape Coral USA 102286 -4028 Arvada USA 102153 -4029 Pueblo USA 102121 -4030 Sandy USA 101853 -4031 Athens-Clarke County USA 101489 -4032 Cambridge USA 101355 -4035 Portsmouth USA 100565 +3880 Shreveport USA 200145 +3946 Bridgeport USA 139529 CREATE INDEX CountryName ON City(Country,Name); EXPLAIN SELECT * FROM City WHERE Country='USA'; @@ -900,9 +827,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName,PRIMARY 38,4 NULL 11 Using sort_union(CountryName,PRIMARY); Using where EXPLAIN SELECT * FROM City -WHERE ((Population > 101000 AND Population < 110000) OR -ID BETWEEN 3500 AND 3800) AND Country='USA' - AND (Name BETWEEN 'P' AND 'T' OR ID BETWEEN 4000 AND 4300); +WHERE ((Population > 101000 AND Population < 1000000) OR +ID BETWEEN 3000 AND 3800) AND Country='USA' + AND (Name BETWEEN 'P' AND 'Z' OR ID BETWEEN 3500 AND 4300) +AND Name LIKE '%port'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City ref PRIMARY,Population,Country,Name,CountryPopulation,CountryName Country 3 const 267 Using where SELECT * FROM City USE INDEX () @@ -938,21 +866,21 @@ ID Name Country Population 4031 Athens-Clarke County USA 101489 4032 Cambridge USA 101355 SELECT * FROM City USE INDEX () -WHERE ((Population > 101000 AND Population < 102000) OR -ID BETWEEN 3790 AND 3800) AND Country='USA' - AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); +WHERE ((Population > 101000 AND Population < 1000000) OR +ID BETWEEN 3000 AND 3800) AND Country='USA' + AND (Name BETWEEN 'P' AND 'Z' OR ID BETWEEN 3500 AND 4300) +AND Name LIKE '%port'; ID Name Country Population -4030 Sandy USA 101853 -4031 Athens-Clarke County USA 101489 -4032 Cambridge USA 101355 +3880 Shreveport USA 200145 +3946 Bridgeport USA 139529 SELECT * FROM City -WHERE ((Population > 101000 AND Population < 102000) OR -ID BETWEEN 3790 AND 3800) AND Country='USA' - AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); +WHERE ((Population > 101000 AND Population < 1000000) OR +ID BETWEEN 3000 AND 3800) AND Country='USA' + AND (Name BETWEEN 'P' AND 'Z' OR ID BETWEEN 3500 AND 4300) +AND Name LIKE '%port'; ID Name Country Population -4030 Sandy USA 101853 -4031 Athens-Clarke County USA 101489 -4032 Cambridge USA 101355 +3880 Shreveport USA 200145 +3946 Bridgeport USA 139529 EXPLAIN SELECT * FROM City WHERE ((Population > 101000 and Population < 102000) OR @@ -1386,3 +1314,4 @@ WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge PRIMARY,idx1,idx2,idx3 idx3,idx2,PRIMARY,idx1 67,13,4,3 NULL 8 Using sort_union(idx3,idx2,PRIMARY,idx1); Using where DROP TABLE t1; +set session optimizer_switch='index_merge_sort_intersection=default'; diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result index 2251119996a..037e23eae5d 100644 --- a/mysql-test/r/range_vs_index_merge_innodb.result +++ b/mysql-test/r/range_vs_index_merge_innodb.result @@ -39,6 +39,7 @@ SELECT COUNT(*) FROM CountryLanguage; COUNT(*) 984 CREATE INDEX Name ON City(Name); +set session optimizer_switch='index_merge_sort_intersection=off'; EXPLAIN SELECT * FROM City WHERE (Population >= 100000 OR Name LIKE 'P%' OR Population < 100000); @@ -72,9 +73,9 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Population Population 4 NULL 458 Using where EXPLAIN SELECT * FROM City -WHERE (Population > 101000 AND Population < 103000); +WHERE (Population > 101000 AND Population < 102000); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population Population 4 NULL 80 Using where +1 SIMPLE City range Population Population 4 NULL 38 Using where EXPLAIN SELECT * FROM City WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')); @@ -89,9 +90,9 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) -AND (Population > 101000 AND Population < 103000); +AND (Population > 101000 AND Population < 102000); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Country,Name Population 4 NULL 80 Using where +1 SIMPLE City range Population,Country,Name Population 4 NULL 38 Using where SELECT * FROM City USE INDEX () WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) AND (Population > 101000 AND Population < 115000); @@ -154,24 +155,20 @@ ID Name Country Population 4032 Cambridge USA 101355 SELECT * FROM City USE INDEX () WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) -AND (Population > 101000 AND Population < 103000); +AND (Population > 101000 AND Population < 102000); ID Name Country Population 637 Mit Ghamr EGY 101801 707 Marbella ESP 101144 -3411 Ceyhan TUR 102412 3792 Tartu EST 101246 -4027 Cape Coral USA 102286 4032 Cambridge USA 101355 SELECT * FROM City WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) -AND (Population > 101000 AND Population < 103000); +AND (Population > 101000 AND Population < 102000); ID Name Country Population 707 Marbella ESP 101144 3792 Tartu EST 101246 4032 Cambridge USA 101355 637 Mit Ghamr EGY 101801 -4027 Cape Coral USA 102286 -3411 Ceyhan TUR 102412 EXPLAIN SELECT * FROM City WHERE (Name < 'Ac'); id select_type table type possible_keys key key_len ref rows Extra @@ -329,9 +326,9 @@ ID Name Country Population 1003 Pemalang IDN 103500 2663 Río Bravo MEX 103901 EXPLAIN -SELECT * FROM City WHERE (ID < 50) OR (ID BETWEEN 100 AND 110); +SELECT * FROM City WHERE (ID < 30) OR (ID BETWEEN 100 AND 150); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 60 Using where +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 79 Using where EXPLAIN SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 300 AND 600); id select_type table type possible_keys key key_len ref rows Extra @@ -354,11 +351,11 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Name Name 35 NULL 133 Using where EXPLAIN SELECT * FROM City -WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) +WHERE ((ID < 30) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 60 Using where +1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 40 Using where EXPLAIN SELECT * FROM City WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) @@ -372,9 +369,9 @@ WHERE ((ID < 600) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 300 AND 600) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 1242 Using where +1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,Population 35,3,4 NULL 188 Using sort_union(Name,Country,Population); Using where SELECT * FROM City USE INDEX () -WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) +WHERE ((ID < 30) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); ID Name Country Population @@ -385,13 +382,10 @@ ID Name Country Population 7 Haag NLD 440900 16 Haarlem NLD 148772 25 Haarlemmermeer NLD 110722 -31 Heerlen NLD 95052 -33 Willemstad ANT 2345 -34 Tirana ALB 270000 100 Paraná ARG 207041 102 Posadas ARG 201273 SELECT * FROM City -WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) +WHERE ((ID < 30) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); ID Name Country Population @@ -402,9 +396,6 @@ ID Name Country Population 7 Haag NLD 440900 16 Haarlem NLD 148772 25 Haarlemmermeer NLD 110722 -31 Heerlen NLD 95052 -33 Willemstad ANT 2345 -34 Tirana ALB 270000 100 Paraná ARG 207041 102 Posadas ARG 201273 SELECT * FROM City USE INDEX() @@ -577,6 +568,20 @@ WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 300 AND 600) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); ID Name Country Population +339 Passo Fundo BRA 166343 +364 Parnaíba BRA 129756 +372 Paranaguá BRA 126076 +379 Palmas BRA 121919 +386 Patos de Minas BRA 119262 +411 Guaratinguetá BRA 103433 +412 Cachoeirinha BRA 103240 +413 Codó BRA 103153 +424 Passos BRA 98570 +430 Paulo Afonso BRA 97291 +435 Parnamirim BRA 96210 +448 Patos BRA 90519 +451 Palhoça BRA 89465 +517 Oldham GBR 103931 1 Kabul AFG 1780000 2 Qandahar AFG 237500 3 Herat AFG 186800 @@ -601,20 +606,6 @@ ID Name Country Population 68 Ajman ARE 114395 129 Oranjestad ABW 29034 191 Hamilton BMU 1200 -339 Passo Fundo BRA 166343 -364 Parnaíba BRA 129756 -372 Paranaguá BRA 126076 -379 Palmas BRA 121919 -386 Patos de Minas BRA 119262 -411 Guaratinguetá BRA 103433 -412 Cachoeirinha BRA 103240 -413 Codó BRA 103153 -424 Passos BRA 98570 -430 Paulo Afonso BRA 97291 -435 Parnamirim BRA 96210 -448 Patos BRA 90519 -451 Palhoça BRA 89465 -517 Oldham GBR 103931 EXPLAIN SELECT * FROM City WHERE Population > 101000 AND Population < 102000; id select_type table type possible_keys key key_len ref rows Extra @@ -727,119 +718,55 @@ SELECT * FROM City WHERE Name LIKE 'P%'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Name Name 35 NULL 235 Using where EXPLAIN -SELECT * FROM City WHERE (Population > 101000 AND Population < 103000); +SELECT * FROM City WHERE (Population > 101000 AND Population < 102000); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population Population 4 NULL 80 Using where +1 SIMPLE City range Population Population 4 NULL 38 Using where EXPLAIN SELECT * FROM City WHERE Country='USA'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City ref Country,CountryPopulation Country 3 const 274 Using where EXPLAIN SELECT * FROM City -WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') +WHERE ((Population > 101000 AND Population < 102000) OR Name LIKE 'Pas%') AND Country='USA'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge Population,Country,Name,CountryPopulation CountryPopulation,Name 7,35 NULL 17 Using sort_union(CountryPopulation,Name); Using where +1 SIMPLE City index_merge Population,Country,Name,CountryPopulation CountryPopulation,Name 7,35 NULL 10 Using sort_union(CountryPopulation,Name); Using where EXPLAIN SELECT * FROM City -WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') -AND Country='USA'; +WHERE ((Population > 101000 AND Population < 1000000) OR Name LIKE 'P%' ) +AND Country='USA' AND Name LIKE '%port'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City ref Population,Country,Name,CountryPopulation Country 3 const 274 Using where SELECT * FROM City -WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') +WHERE ((Population > 101000 AND Population < 102000) OR Name LIKE 'Pas%') AND Country='USA'; ID Name Country Population 3943 Pasadena USA 141674 3953 Pasadena USA 133936 -4023 Gary USA 102746 -4024 Berkeley USA 102743 -4025 Santa Clara USA 102361 -4026 Green Bay USA 102313 -4027 Cape Coral USA 102286 -4028 Arvada USA 102153 -4029 Pueblo USA 102121 4030 Sandy USA 101853 4031 Athens-Clarke County USA 101489 4032 Cambridge USA 101355 SELECT * FROM City USE INDEX () -WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') +WHERE ((Population > 101000 AND Population < 102000) OR Name LIKE 'Pas%') AND Country='USA'; ID Name Country Population 3943 Pasadena USA 141674 3953 Pasadena USA 133936 -4023 Gary USA 102746 -4024 Berkeley USA 102743 -4025 Santa Clara USA 102361 -4026 Green Bay USA 102313 -4027 Cape Coral USA 102286 -4028 Arvada USA 102153 -4029 Pueblo USA 102121 4030 Sandy USA 101853 4031 Athens-Clarke County USA 101489 4032 Cambridge USA 101355 SELECT * FROM City -WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') -AND Country='USA'; +WHERE ((Population > 101000 AND Population < 1000000) OR Name LIKE 'P%') +AND Country='USA' AND Name LIKE '%port'; ID Name Country Population -3797 Philadelphia USA 1517550 -3798 Phoenix USA 1321045 -3820 Portland USA 529121 -3844 Pittsburgh USA 334563 -3870 Plano USA 222030 -3912 Providence USA 173618 -3930 Pomona USA 149473 -3932 Paterson USA 149222 -3943 Pasadena USA 141674 -3951 Pembroke Pines USA 137427 -3953 Pasadena USA 133936 -3967 Paradise USA 124682 -3986 Palmdale USA 116670 -3996 Peoria USA 112936 -4007 Peoria USA 108364 -4016 Provo USA 105166 -4023 Gary USA 102746 -4024 Berkeley USA 102743 -4025 Santa Clara USA 102361 -4026 Green Bay USA 102313 -4027 Cape Coral USA 102286 -4028 Arvada USA 102153 -4029 Pueblo USA 102121 -4030 Sandy USA 101853 -4031 Athens-Clarke County USA 101489 -4032 Cambridge USA 101355 -4035 Portsmouth USA 100565 +3880 Shreveport USA 200145 +3946 Bridgeport USA 139529 SELECT * FROM City USE INDEX () -WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') -AND Country='USA'; +WHERE ((Population > 101000 AND Population < 1000000) OR Name LIKE 'P%') +AND Country='USA' AND Name LIKE '%port'; ID Name Country Population -3797 Philadelphia USA 1517550 -3798 Phoenix USA 1321045 -3820 Portland USA 529121 -3844 Pittsburgh USA 334563 -3870 Plano USA 222030 -3912 Providence USA 173618 -3930 Pomona USA 149473 -3932 Paterson USA 149222 -3943 Pasadena USA 141674 -3951 Pembroke Pines USA 137427 -3953 Pasadena USA 133936 -3967 Paradise USA 124682 -3986 Palmdale USA 116670 -3996 Peoria USA 112936 -4007 Peoria USA 108364 -4016 Provo USA 105166 -4023 Gary USA 102746 -4024 Berkeley USA 102743 -4025 Santa Clara USA 102361 -4026 Green Bay USA 102313 -4027 Cape Coral USA 102286 -4028 Arvada USA 102153 -4029 Pueblo USA 102121 -4030 Sandy USA 101853 -4031 Athens-Clarke County USA 101489 -4032 Cambridge USA 101355 -4035 Portsmouth USA 100565 +3880 Shreveport USA 200145 +3946 Bridgeport USA 139529 CREATE INDEX CountryName ON City(Country,Name); EXPLAIN SELECT * FROM City WHERE Country='USA'; @@ -901,9 +828,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName,PRIMARY 38,4 NULL 10 Using sort_union(CountryName,PRIMARY); Using where EXPLAIN SELECT * FROM City -WHERE ((Population > 101000 AND Population < 110000) OR -ID BETWEEN 3500 AND 3800) AND Country='USA' - AND (Name BETWEEN 'P' AND 'T' OR ID BETWEEN 4000 AND 4300); +WHERE ((Population > 101000 AND Population < 1000000) OR +ID BETWEEN 3000 AND 3800) AND Country='USA' + AND (Name BETWEEN 'P' AND 'Z' OR ID BETWEEN 3500 AND 4300) +AND Name LIKE '%port'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City ref PRIMARY,Population,Country,Name,CountryPopulation,CountryName Country 3 const 274 Using where SELECT * FROM City USE INDEX () @@ -939,21 +867,21 @@ ID Name Country Population 4031 Athens-Clarke County USA 101489 4032 Cambridge USA 101355 SELECT * FROM City USE INDEX () -WHERE ((Population > 101000 AND Population < 102000) OR -ID BETWEEN 3790 AND 3800) AND Country='USA' - AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); +WHERE ((Population > 101000 AND Population < 1000000) OR +ID BETWEEN 3000 AND 3800) AND Country='USA' + AND (Name BETWEEN 'P' AND 'Z' OR ID BETWEEN 3500 AND 4300) +AND Name LIKE '%port'; ID Name Country Population -4030 Sandy USA 101853 -4031 Athens-Clarke County USA 101489 -4032 Cambridge USA 101355 +3880 Shreveport USA 200145 +3946 Bridgeport USA 139529 SELECT * FROM City -WHERE ((Population > 101000 AND Population < 102000) OR -ID BETWEEN 3790 AND 3800) AND Country='USA' - AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); +WHERE ((Population > 101000 AND Population < 1000000) OR +ID BETWEEN 3000 AND 3800) AND Country='USA' + AND (Name BETWEEN 'P' AND 'Z' OR ID BETWEEN 3500 AND 4300) +AND Name LIKE '%port'; ID Name Country Population -4030 Sandy USA 101853 -4031 Athens-Clarke County USA 101489 -4032 Cambridge USA 101355 +3880 Shreveport USA 200145 +3946 Bridgeport USA 139529 EXPLAIN SELECT * FROM City WHERE ((Population > 101000 and Population < 102000) OR @@ -1387,4 +1315,5 @@ WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge PRIMARY,idx1,idx2,idx3 idx3,idx2,idx1,PRIMARY 67,13,3,4 NULL 9 Using sort_union(idx3,idx2,idx1,PRIMARY); Using where DROP TABLE t1; +set session optimizer_switch='index_merge_sort_intersection=default'; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index cbb6149a148..9cebd8b9f98 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -3667,8 +3667,6 @@ CREATE TABLE t1 (a int, b int auto_increment, PRIMARY KEY (b)); CREATE TABLE t2 (x int auto_increment, y int, z int, PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b)); SET SESSION sort_buffer_size = 32 * 1024; -Warnings: -Warning 1292 Truncated incorrect sort_buffer_size value: '32768' SELECT SQL_NO_CACHE COUNT(*) FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c FROM t1) t; @@ -4104,8 +4102,6 @@ INSERT INTO `t1` VALUES ('asdf','2007-02-08 01:11:26'); INSERT INTO `t2` VALUES ('abcdefghijk'); INSERT INTO `t2` VALUES ('asdf'); SET session sort_buffer_size=8192; -Warnings: -Warning 1292 Truncated incorrect sort_buffer_size value: '8192' SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2; d1 1 diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 832c679f8d5..f1133b7fb4d 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -971,6 +971,7 @@ tmpdir # select * from information_schema.session_variables where variable_name like 'tmpdir'; VARIABLE_NAME VARIABLE_VALUE TMPDIR # +set sort_buffer_size=1024*8; select @@ssl_ca, @@ssl_capath, @@ssl_cert, @@ssl_cipher, @@ssl_key; @@ssl_ca @@ssl_capath @@ssl_cert @@ssl_cipher @@ssl_key # # # # # diff --git a/mysql-test/t/index_intersect.test b/mysql-test/t/index_intersect.test new file mode 100644 index 00000000000..0fe89b714fa --- /dev/null +++ b/mysql-test/t/index_intersect.test @@ -0,0 +1,385 @@ +--disable_warnings +DROP TABLE IF EXISTS t1,t2,t3,t4; +DROP DATABASE IF EXISTS world; +--enable_warnings + +set names utf8; + +CREATE DATABASE world; + +use world; + +--source include/world_schema.inc + +--disable_query_log +--disable_result_log +--disable_warnings +--source include/world.inc +--enable_warnings +--enable_result_log +--enable_query_log + +SELECT COUNT(*) FROM Country; +SELECT COUNT(*) FROM City; +SELECT COUNT(*) FROM CountryLanguage; + +CREATE INDEX Name ON City(Name); + +--disable_query_log +--disable_result_log +--disable_warnings +ANALYZE TABLE City; +--enable_warnings +--enable_result_log +--enable_query_log + + +SET SESSION optimizer_switch='index_merge_sort_intersection=on'; + +SELECT COUNT(*) FROM City; + +# The output of the next 6 queries tells us about selectivities +# of the conditions utilized in 4 queries following after them + +SELECT COUNT(*) FROM City WHERE Name LIKE 'C%'; +SELECT COUNT(*) FROM City WHERE Name LIKE 'M%'; +SELECT COUNT(*) FROM City WHERE Population > 1000000; +SELECT COUNT(*) FROM City WHERE Population > 500000; +SELECT COUNT(*) FROM City WHERE Population > 300000; +SELECT COUNT(*) FROM City WHERE Population > 5000000; + +# The pattern of the WHERE condition used in the following 4 queries is +# range(key1) AND range(key2) +# Varying values of the constants in the conjuncts of the condition +# we can get either an index intersection retrieval over key1 and key2 +# or a range index scan for one of these indexes + +EXPLAIN +SELECT * FROM City WHERE + Name LIKE 'C%' AND Population > 1000000; + +EXPLAIN +SELECT * FROM City WHERE + Name LIKE 'M%' AND Population > 500000; + +EXPLAIN +SELECT * FROM City + WHERE Name LIKE 'M%' AND Population > 300000; + +EXPLAIN +SELECT * FROM City + WHERE Name LIKE 'M%' AND Population > 5000000; + + +# The following 8 queries check that +# the previous 4 plans are valid and return +# the correct results when executed + + +SELECT * FROM City USE INDEX () + WHERE Name LIKE 'C%' AND Population > 1000000; + +SELECT * FROM City + WHERE Name LIKE 'C%' AND Population > 1000000; + + +SELECT * FROM City USE INDEX () + WHERE Name LIKE 'M%' AND Population > 500000; + +SELECT * FROM City + WHERE Name LIKE 'M%' AND Population > 500000; + + +SELECT * FROM City USE INDEX () + WHERE Name LIKE 'M%' AND Population > 300000; + +SELECT * FROM City + WHERE Name LIKE 'M%' AND Population > 300000; + + +SELECT * FROM City USE INDEX () + WHERE Name LIKE 'M%' AND Population > 5000000; + +SELECT * FROM City + WHERE Name LIKE 'M%' AND Population > 5000000; + + +# The output of the next 7 queries tells us about selectivities +# of the conditions utilized in 3 queries following after them + +SELECT COUNT(*) FROM City WHERE Name BETWEEN 'M' AND 'N'; +SELECT COUNT(*) FROM City WHERE Name BETWEEN 'G' AND 'J'; +SELECT COUNT(*) FROM City WHERE Population > 1000000; +SELECT COUNT(*) FROM City WHERE Population > 700000; +SELECT COUNT(*) FROM City WHERE Population > 500000; +SELECT COUNT(*) FROM City WHERE Country LIKE 'C%'; +SELECT COUNT(*) FROM City WHERE Country LIKE 'L%'; + + +# The pattern of the WHERE condition used in the following 3 queries is +# range(key1) AND range(key2) AND range(key3) +# Varying values of the constants in the conjuncts of the condition +# we can get index intersection over different pairs of keys: +# over(key1,key2), over(key1,key3) and over(key2,key3) + + +EXPLAIN +SELECT * FROM City + WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; + +EXPLAIN +SELECT * FROM City + WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'L%'; + +EXPLAIN +SELECT * FROM City + WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; + + +# The following 6 queries check that +# the previous 3 plans are valid and return +# the correct results when executed + + +SELECT * FROM City USE INDEX () + WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; + +SELECT * FROM City + WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; + + +SELECT * FROM City USE INDEX () + WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; + +SELECT * FROM City + WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; + + +SELECT * FROM City USE INDEX () + WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; + +SELECT * FROM City + WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; + + +# The output of the next 9 queries tells us about selectivities +# of the conditions utilized in 5 queries following after them + +SELECT COUNT(*) FROM City WHERE ID BETWEEN 500 AND 999; +SELECT COUNT(*) FROM City WHERE ID BETWEEN 3500 AND 3999; +SELECT COUNT(*) FROM City WHERE ID BETWEEN 1 AND 1000; +SELECT COUNT(*) FROM City WHERE Population > 700000; +SELECT COUNT(*) FROM City WHERE Population > 1000000; +SELECT COUNT(*) FROM City WHERE Population > 300000; +SELECT COUNT(*) FROM City WHERE Country LIKE 'C%'; +SELECT COUNT(*) FROM City WHERE Country LIKE 'A%'; +SELECT COUNT(*) FROM City WHERE Country BETWEEN 'S' AND 'Z'; + + +# The pattern of the WHERE condition used in the following 5 queries is +# range(key1) AND range(key2) AND range(key3) +# with key1 happens to be a primary key (it matters only for InnoDB) +# Varying values of the constants in the conjuncts of the condition +# we can get index intersection either over all three keys, or over +# different pairs, or a range sacn over one of these keys. +# Bear in mind that the condition (Country LIKE 'A%') is actually +# equivalent to the condition (Country BETWEEN 'A' AND 'B') for the +# tested instance the table City. + + +EXPLAIN +SELECT * FROM City + WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%'; + +EXPLAIN +SELECT * FROM City + WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; + +EXPLAIN +SELECT * FROM City + WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%'; + +EXPLAIN +SELECT * FROM City + WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000 + AND Country BETWEEN 'S' AND 'Z'; + +EXPLAIN +SELECT * FROM City + WHERE ID BETWEEN 1 AND 1000 AND Population > 700000 + AND Country BETWEEN 'S' AND 'Z' ; + + +# The following 10 queries check that +# the previous 5 plans are valid and return +# the correct results when executed + + +SELECT * FROM City USE INDEX () + WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%'; + +SELECT * FROM City + WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%'; + + +SELECT * FROM City USE INDEX () + WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; + +SELECT * FROM City + WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; + + +SELECT * FROM City USE INDEX () + WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%'; + +SELECT * FROM City + WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%'; + + +SELECT * FROM City USE INDEX () + WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000 + AND Country BETWEEN 'S' AND 'Z'; + +SELECT * FROM City + WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000 + AND Country BETWEEN 'S' AND 'Z'; + + +SELECT * FROM City USE INDEX () + WHERE ID BETWEEN 1 AND 1000 AND Population > 700000 + AND Country BETWEEN 'S' AND 'Z' ; + +SELECT * FROM City + WHERE ID BETWEEN 1 AND 1000 AND Population > 700000 + AND Country BETWEEN 'S' AND 'Z' ; + + +SET SESSION sort_buffer_size = 2048; + + +# The following EXPLAIN command demonstrate that the execution plans +# may be different if sort_buffer_size is set to a small value + + +EXPLAIN +SELECT * FROM City WHERE + Name LIKE 'C%' AND Population > 1000000; + +EXPLAIN +SELECT * FROM City WHERE + Name LIKE 'M%' AND Population > 500000; + + +EXPLAIN +SELECT * FROM City + WHERE Name LIKE 'C%' AND Population > 1000000 AND Country LIKE 'C%'; + +EXPLAIN +SELECT * FROM City + WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; + +EXPLAIN +SELECT * FROM City + WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; + + +EXPLAIN +SELECT * FROM City + WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; + +EXPLAIN +SELECT * FROM City + WHERE ID < 1000 AND Population > 700000 AND Country LIKE 'C%'; + + +#Yet the query themselves return the correct results in this case as well + + +SELECT * FROM City WHERE + Name LIKE 'C%' AND Population > 1000000; + +SELECT * FROM City WHERE + Name LIKE 'M%' AND Population > 500000; + + +SELECT * FROM City + WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; + +SELECT * FROM City + WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; + +SELECT * FROM City + WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; + + +SELECT * FROM City + WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; + +SELECT * FROM City + WHERE ID < 1000 AND Population > 700000 AND Country LIKE 'C%'; + + +SET SESSION sort_buffer_size = default; + +# Instead of the index on the column Country create two compound indexes +# including this column as the first component + +DROP INDEX Country ON City; + +CREATE INDEX CountryID ON City(Country,ID); +CREATE INDEX CountryName ON City(Country,Name); + +--disable_query_log +--disable_result_log +--disable_warnings +ANALYZE TABLE City; +--enable_warnings +--enable_result_log +--enable_query_log + +# Check that the first component of a compound index can be used for +# index intersection, even in the cases when we have a ref access +# for this component + +EXPLAIN +SELECT * FROM City + WHERE Country LIKE 'M%' AND Population > 700000; + +EXPLAIN +SELECT * FROM City + WHERE Country='CHN' AND Population > 1000000; + +EXPLAIN +SELECT * FROM City + WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%'; + + +# Check that the previous 3 plans return the right results when executed + + +SELECT * FROM City USE INDEX () + WHERE Country LIKE 'M%' AND Population > 700000; + +SELECT * FROM City + WHERE Country LIKE 'M%' AND Population > 700000; + + +SELECT * FROM City USE INDEX () + WHERE Country='CHN' AND Population > 1000000; + +SELECT * FROM City + WHERE Country='CHN' AND Population > 1000000; + + +SELECT * FROM City USE INDEX () + WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%'; + +SELECT * FROM City + WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%'; + + +DROP DATABASE world; + +use test; + +SET SESSION optimizer_switch='index_merge_sort_intersection=on'; diff --git a/mysql-test/t/index_intersect_innodb.test b/mysql-test/t/index_intersect_innodb.test new file mode 100644 index 00000000000..22c0e807558 --- /dev/null +++ b/mysql-test/t/index_intersect_innodb.test @@ -0,0 +1,7 @@ +--source include/have_innodb.inc + +SET SESSION STORAGE_ENGINE='InnoDB'; + +--source t/index_intersect.test + +SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/t/index_merge_innodb.test b/mysql-test/t/index_merge_innodb.test index e68f414e0bc..161ef0856ae 100644 --- a/mysql-test/t/index_merge_innodb.test +++ b/mysql-test/t/index_merge_innodb.test @@ -18,6 +18,11 @@ let $engine_type= InnoDB; # InnoDB does not support Merge tables (affects include/index_merge1.inc) let $merge_table_support= 0; +set @optimizer_switch_save= @@optimizer_switch; + +set optimizer_switch='index_merge_sort_intersection=off'; + + # The first two tests are disabled because of non deterministic explain output. # If include/index_merge1.inc can be enabled for InnoDB and all other # storage engines, please remove the subtest for Bug#21277 from @@ -82,3 +87,5 @@ SELECT COUNT(*) FROM WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; DROP TABLE t1; + +set optimizer_switch= @optimizer_switch_save; diff --git a/mysql-test/t/index_merge_myisam.test b/mysql-test/t/index_merge_myisam.test index 0c4b9c6886c..26f7f0518c6 100644 --- a/mysql-test/t/index_merge_myisam.test +++ b/mysql-test/t/index_merge_myisam.test @@ -14,6 +14,10 @@ let $engine_type= MyISAM; # MyISAM supports Merge tables let $merge_table_support= 1; +set @optimizer_switch_save= @@optimizer_switch; + +set optimizer_switch='index_merge_sort_intersection=off'; + --source include/index_merge1.inc --source include/index_merge_ror.inc --source include/index_merge2.inc @@ -164,7 +168,7 @@ set optimizer_switch='default,index_merge=off'; explain select * from t1 where a=10 and b=10; --echo No intersect if it is disabled: -set optimizer_switch='default,index_merge_intersection=off'; +set optimizer_switch='default,index_merge_sort_intersection=off,index_merge_intersection=off'; explain select * from t1 where a=10 and b=10; --echo Do intersect when union was disabled @@ -195,3 +199,5 @@ show variables like 'optimizer_switch'; drop table t0, t1; +set optimizer_switch= @optimizer_switch_save; + diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index de380e09e8a..2d2e3e541e2 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -843,7 +843,7 @@ DROP TABLE t1; --echo # create table t1(a int, b tinytext); insert into t1 values (1,2),(3,2); -set session sort_buffer_size= 30000; +set session sort_buffer_size= 1000; set session max_sort_length= 2180; --error 1038 select * from t1 order by b; diff --git a/mysql-test/t/range_vs_index_merge.test b/mysql-test/t/range_vs_index_merge.test index f57fced6da6..7ddd2cb5cea 100755 --- a/mysql-test/t/range_vs_index_merge.test +++ b/mysql-test/t/range_vs_index_merge.test @@ -33,6 +33,8 @@ ANALYZE TABLE City; --enable_result_log --enable_query_log +set session optimizer_switch='index_merge_sort_intersection=off'; + # The following 4 queries are added for code coverage #the exptected # of rows differ on 32-bit and 64-bit platforms for innodb @@ -68,7 +70,7 @@ SELECT * FROM City EXPLAIN SELECT * FROM City - WHERE (Population > 101000 AND Population < 103000); + WHERE (Population > 101000 AND Population < 102000); EXPLAIN SELECT * FROM City @@ -88,7 +90,7 @@ SELECT * FROM City EXPLAIN SELECT * FROM City WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) - AND (Population > 101000 AND Population < 103000); + AND (Population > 101000 AND Population < 102000); # The following 4 queries check that the plans # for the previous 2 plans are valid @@ -103,11 +105,11 @@ SELECT * FROM City SELECT * FROM City USE INDEX () WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) - AND (Population > 101000 AND Population < 103000); + AND (Population > 101000 AND Population < 102000); SELECT * FROM City WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) - AND (Population > 101000 AND Population < 103000); + AND (Population > 101000 AND Population < 102000); # The output of the next 7 commands tells us about selectivities # of the conditions utilized in 4 queries following after them @@ -197,7 +199,7 @@ SELECT * FROM City # of the conditions utilized in 3 queries following after them EXPLAIN -SELECT * FROM City WHERE (ID < 50) OR (ID BETWEEN 100 AND 110); +SELECT * FROM City WHERE (ID < 30) OR (ID BETWEEN 100 AND 150); EXPLAIN SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 300 AND 600); EXPLAIN @@ -219,7 +221,7 @@ SELECT * FROM City WHERE Name LIKE 'Ha%' OR Name LIKE 'Pa%' ; EXPLAIN SELECT * FROM City - WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) + WHERE ((ID < 30) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); @@ -240,12 +242,12 @@ SELECT * FROM City # for the previous 3 plans are valid SELECT * FROM City USE INDEX () - WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) + WHERE ((ID < 30) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); SELECT * FROM City - WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) + WHERE ((ID < 30) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); @@ -361,7 +363,7 @@ SELECT * FROM City WHERE Name LIKE 'Pas%'; EXPLAIN SELECT * FROM City WHERE Name LIKE 'P%'; EXPLAIN -SELECT * FROM City WHERE (Population > 101000 AND Population < 103000); +SELECT * FROM City WHERE (Population > 101000 AND Population < 102000); EXPLAIN SELECT * FROM City WHERE Country='USA'; @@ -374,32 +376,32 @@ SELECT * FROM City WHERE Country='USA'; EXPLAIN SELECT * FROM City - WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') + WHERE ((Population > 101000 AND Population < 102000) OR Name LIKE 'Pas%') AND Country='USA'; EXPLAIN SELECT * FROM City - WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') - AND Country='USA'; + WHERE ((Population > 101000 AND Population < 1000000) OR Name LIKE 'P%' ) + AND Country='USA' AND Name LIKE '%port'; # The following 4 queries check that the plans # for the previous 2 plans are valid SELECT * FROM City - WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') + WHERE ((Population > 101000 AND Population < 102000) OR Name LIKE 'Pas%') AND Country='USA'; SELECT * FROM City USE INDEX () - WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') + WHERE ((Population > 101000 AND Population < 102000) OR Name LIKE 'Pas%') AND Country='USA'; SELECT * FROM City - WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') - AND Country='USA'; + WHERE ((Population > 101000 AND Population < 1000000) OR Name LIKE 'P%') + AND Country='USA' AND Name LIKE '%port'; SELECT * FROM City USE INDEX () - WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') - AND Country='USA'; + WHERE ((Population > 101000 AND Population < 1000000) OR Name LIKE 'P%') + AND Country='USA' AND Name LIKE '%port'; CREATE INDEX CountryName ON City(Country,Name); @@ -463,9 +465,10 @@ SELECT * FROM City EXPLAIN SELECT * FROM City - WHERE ((Population > 101000 AND Population < 110000) OR - ID BETWEEN 3500 AND 3800) AND Country='USA' - AND (Name BETWEEN 'P' AND 'T' OR ID BETWEEN 4000 AND 4300); + WHERE ((Population > 101000 AND Population < 1000000) OR + ID BETWEEN 3000 AND 3800) AND Country='USA' + AND (Name BETWEEN 'P' AND 'Z' OR ID BETWEEN 3500 AND 4300) + AND Name LIKE '%port'; # The following 6 queries check that the plans # for the previous 3 plans are valid @@ -491,14 +494,16 @@ SELECT * FROM City AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032); SELECT * FROM City USE INDEX () - WHERE ((Population > 101000 AND Population < 102000) OR - ID BETWEEN 3790 AND 3800) AND Country='USA' - AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); + WHERE ((Population > 101000 AND Population < 1000000) OR + ID BETWEEN 3000 AND 3800) AND Country='USA' + AND (Name BETWEEN 'P' AND 'Z' OR ID BETWEEN 3500 AND 4300) + AND Name LIKE '%port'; SELECT * FROM City - WHERE ((Population > 101000 AND Population < 102000) OR - ID BETWEEN 3790 AND 3800) AND Country='USA' - AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); + WHERE ((Population > 101000 AND Population < 1000000) OR + ID BETWEEN 3000 AND 3800) AND Country='USA' + AND (Name BETWEEN 'P' AND 'Z' OR ID BETWEEN 3500 AND 4300) + AND Name LIKE '%port'; # The pattern of the WHERE condition used in the following query is @@ -918,3 +923,7 @@ SELECT COUNT(*) FROM t1 (pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ; DROP TABLE t1; + +#the following command must be the last one in the file +set session optimizer_switch='index_merge_sort_intersection=default'; + diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 3e9dc5e39d3..3bd192f8cd1 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -736,6 +736,7 @@ select * from information_schema.session_variables where variable_name like 'tmp # Bug #19606: make ssl settings available via SHOW VARIABLES and @@variables # # Don't actually output, since it depends on the system +set sort_buffer_size=1024*8; --replace_column 1 # 2 # 3 # 4 # 5 # select @@ssl_ca, @@ssl_capath, @@ssl_cert, @@ssl_cipher, @@ssl_key; --replace_column 2 # diff --git a/sql/filesort.cc b/sql/filesort.cc index 2bc1a694126..42ce33af1ca 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -1750,3 +1750,4 @@ void change_double_for_sort(double nr,uchar *to) } } } + diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index efb92108781..534e0ae9bed 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -338,7 +338,7 @@ protected: Number of comparisons of table rowids equivalent to reading one row from a table. */ -#define TIME_FOR_COMPARE_ROWID (TIME_FOR_COMPARE*2) +#define TIME_FOR_COMPARE_ROWID (TIME_FOR_COMPARE*100) /* For sequential disk seeks the cost formula is: @@ -542,12 +542,13 @@ protected: #define OPTIMIZER_SWITCH_INDEX_MERGE_UNION 2 #define OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION 4 #define OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT 8 +#define OPTIMIZER_SWITCH_INDEX_MERGE_SORT_INTERSECT 16 #ifdef DBUG_OFF -# define OPTIMIZER_SWITCH_LAST 16 -#else -# define OPTIMIZER_SWITCH_TABLE_ELIMINATION 16 # define OPTIMIZER_SWITCH_LAST 32 +#else +# define OPTIMIZER_SWITCH_TABLE_ELIMINATION 32 +# define OPTIMIZER_SWITCH_LAST 64 #endif #ifdef DBUG_OFF @@ -555,12 +556,14 @@ protected: # define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \ OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \ OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \ - OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT) + OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \ + OPTIMIZER_SWITCH_INDEX_MERGE_SORT_INTERSECT) #else # define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \ OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \ OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \ OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \ + OPTIMIZER_SWITCH_INDEX_MERGE_SORT_INTERSECT | \ OPTIMIZER_SWITCH_TABLE_ELIMINATION) #endif @@ -2232,6 +2235,8 @@ ha_rows filesort(THD *thd, TABLE *form,struct st_sort_field *sortorder, ha_rows max_rows, bool sort_positions, ha_rows *examined_rows); void filesort_free_buffers(TABLE *table, bool full); +double get_merge_many_buffs_cost(uint *buffer, uint last_n_elems, + int elem_size); void change_double_for_sort(double nr,uchar *to); double my_double_round(double value, longlong dec, bool dec_unsigned, bool truncate); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1218ee666e1..af778d270d4 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -335,7 +335,7 @@ TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"", static const char *optimizer_switch_names[]= { "index_merge","index_merge_union","index_merge_sort_union", - "index_merge_intersection", + "index_merge_intersection","index_merge_sort_intersection", #ifndef DBUG_OFF "table_elimination", #endif @@ -349,6 +349,7 @@ static const unsigned int optimizer_switch_names_len[]= sizeof("index_merge_union") - 1, sizeof("index_merge_sort_union") - 1, sizeof("index_merge_intersection") - 1, + sizeof("index_merge_sort_intersection") - 1, #ifndef DBUG_OFF sizeof("table_elimination") - 1, #endif @@ -428,7 +429,8 @@ static const char *sql_mode_str= "OFF"; /* Text representation for OPTIMIZER_SWITCH_DEFAULT */ static const char *optimizer_switch_str="index_merge=on,index_merge_union=on," "index_merge_sort_union=on," - "index_merge_intersection=on" + "index_merge_intersection=on," + "index_merge_sort_intersection=on" #ifndef DBUG_OFF ",table_elimination=on"; #else @@ -7290,7 +7292,8 @@ thread is in the relay logs.", 0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0}, {"optimizer_switch", OPT_OPTIMIZER_SWITCH, "optimizer_switch=option=val[,option=val...], where option={index_merge, " - "index_merge_union, index_merge_sort_union, index_merge_intersection" + "index_merge_union, index_merge_sort_union, index_merge_intersection, " + "index_merge_sort_intersection" #ifndef DBUG_OFF ", table_elimination" #endif diff --git a/sql/opt_range.cc b/sql/opt_range.cc index ff2f5f28aa0..f088cf87bca 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1793,7 +1793,7 @@ QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT() QUICK_INDEX_INTERSECT_SELECT::QUICK_INDEX_INTERSECT_SELECT(THD *thd_param, TABLE *table) - :pk_quick_select(NULL), thd(thd_param) + :unique(NULL), pk_quick_select(NULL), thd(thd_param) { DBUG_ENTER("QUICK_INDEX_INTERSECT_SELECT::QUICK_INDEX_INTERSECT_SELECT"); index= MAX_KEY; @@ -2642,7 +2642,7 @@ public: virtual ~TRP_INDEX_INTERSECT() {} /* Remove gcc warning */ QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows, MEM_ROOT *parent_alloc); - TRP_RANGE **range_scans; /* array of ptrs to plans of merged scans */ + TRP_RANGE **range_scans; /* array of ptrs to plans of intersected scans */ TRP_RANGE **range_scans_end; /* end of the array */ }; @@ -2724,7 +2724,12 @@ typedef struct st_index_scan_info /* Set of intervals over key fields that will be used for row retrieval. */ SEL_ARG *sel_arg; - /* Fields used in the query and covered by this ROR scan. */ + KEY *key_info; + uint used_key_parts; + + MY_BITMAP used_fields; + + /* Fields used in the query and covered by ROR scan. */ MY_BITMAP covered_fields; uint used_fields_covered; /* # of set bits in covered_fields */ int key_rec_length; /* length of key record (including rowid) */ @@ -3056,18 +3061,17 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, best_trp= rori_trp; } } -#if 1 -#else - if (optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE)) + if (optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE) && + optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE_SORT_INTERSECT)) { if ((intersect_trp= get_best_index_intersect(¶m, tree, best_read_time))) { best_trp= intersect_trp; best_read_time= best_trp->read_cost; + } } -#endif if (optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE)) { @@ -4498,7 +4502,9 @@ TABLE_READ_PLAN *get_best_disjunct_quick(PARAM *param, SEL_IMERGE *imerge, imerge_cost += Unique::get_use_cost(param->imerge_cost_buff, (uint)non_cpk_scan_records, param->table->file->ref_length, - param->thd->variables.sortbuff_size); + param->thd->variables.sortbuff_size, + TIME_FOR_COMPARE_ROWID, + FALSE, NULL); DBUG_PRINT("info",("index_merge total cost: %g (wanted: less then %g)", imerge_cost, read_time)); if (imerge_cost < read_time) @@ -4731,82 +4737,670 @@ TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge, DBUG_RETURN(trp); } + +/* + This structure contains the info common for all steps of a partial + index intersection plan. Morever it contains also the info common + for index intersect plans. This info is filled in by the function + prepare_search_best just before searching for the best index + intersection plan. +*/ + +typedef struct st_common_index_intersection_info +{ + PARAM *param; /* context info for range optimizations */ + uint key_size; /* size of a ROWID element stored in Unique object */ + uint compare_factor; /* 1/compare - cost to compare two ROWIDs */ + ulonglong max_memory_size; /* maximum space allowed for Unique objects */ + ha_rows table_cardinality; /* estimate of the number of records in table */ + double cutoff_cost; /* discard index intersects with greater costs */ + INDEX_SCAN_INFO *cpk_scan; /* clustered primary key used in intersection */ + + bool in_memory; /* unique object for intersection is completely in memory */ + /* estimate of the number of records filtered out from the first scan by + ranges for the clustered primary key scan (cpk_scan) */ + ha_rows filtered_out_records; + double filter_cost; /* cost of checking the the cpk_scan rabhe conditions */ + + INDEX_SCAN_INFO **search_scans; /* scans possibly included in intersect */ + uint n_search_scans; /* number of elements in search_scans */ + + bool best_uses_cpk; /* current best intersect uses clustered primary key */ + double best_cost; /* cost of the current best index intersection */ + /* estimate of the number of records in the current best intersection */ + ha_rows best_records; + uint best_length; /* number of indexes in the current best intersection */ + INDEX_SCAN_INFO **best_intersect; /* the current best index intersection */ + + uint *buff_elems; /* buffer to calculate cost of index intersection */ + +} COMMON_INDEX_INTERSECTION_INFO; + + +/* + This structure contains the info specific for one step of an index + intersection plan. The structure is filled in by the function + check_index_intersect_extension. +*/ + +typedef struct st_partial_index_intersection_info +{ + COMMON_INDEX_INTERSECTION_INFO *common_info; /* shared by index intersects */ + uint length; /* number of index scans in the partial intersection */ + ha_rows records; /* estimate of the number of records in intersection */ + double cost; /* cost of the partial index intersection */ + + /* estimate of total number of records in all index scans of intersection */ + ha_rows records_in_scans; + + /* total cost of the scans of indexes from the partial index intersection */ + double index_read_cost; + + bool with_cpk_filter; /* cpk filter is to be used for the first scan */ + bool in_memory; /* uses unique object in memory */ + double in_memory_cost; /* cost of using unique object in memory */ + + MY_BITMAP *intersect_fields; /* bitmap of fields used in intersection */ +} PARTIAL_INDEX_INTERSECTION_INFO; + + +/* Check whether two indexes have the same first n components */ + +static +bool same_index_prefix(KEY *key1, KEY *key2, uint used_parts) +{ + KEY_PART_INFO *part1= key1->key_part; + KEY_PART_INFO *part2= key2->key_part; + for(uint i= 0; i < used_parts; i++, part1++, part2++) + { + if (part1->fieldnr != part2->fieldnr) + return FALSE; + } + return TRUE; +} + + +/* Create a bitmap for all fields of a table */ + +static +bool create_fields_bitmap(PARAM *param, MY_BITMAP *fields_bitmap) +{ + my_bitmap_map *bitmap_buf; + + if (!(bitmap_buf= (my_bitmap_map *) alloc_root(param->mem_root, + param->fields_bitmap_size))) + return TRUE; + if (bitmap_init(fields_bitmap, bitmap_buf, param->table->s->fields, FALSE)) + return TRUE; + + return FALSE; +} + +/* Compare two indexes scans for sort before search for the best intersection */ + +static +int cmp_intersect_index_scan(INDEX_SCAN_INFO **a, INDEX_SCAN_INFO **b) +{ + return (*a)->records < (*b)->records ? + -1 : (*a)->records == (*b)->records ? 0 : 1; +} + + +/* + Round up table cardinality read from statistics provided by engine. + This function should go away when mysql test will allow to handle + more or less easily in the test suites deviations of InnoDB + statistical data. +*/ + +static inline +ha_rows get_table_cardinality_for_index_intersect(TABLE *table) +{ + if (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) + return table->file->stats.records; + else + { + ha_rows d; + double q; + for (q= table->file->stats.records, d= 1 ; q >= 10; q/= 10, d*= 10 ) ; + return (ha_rows) (round(q) * d); + } +} + + +/* + Prepare to search for the best index intersection + + SYNOPSIS + prepare_search_best_index_intersect() + param common info about index ranges + tree tree of ranges for indexes than can be intersected + common OUT info needed for search to be filled by the function + init OUT info for an initial pseudo step of the intersection plans + cutoff_cost cut off cost of the interesting index intersection + + NOTES + The function initializes all fields of the structure 'common' to be used + when searching for the best intersection plan. It also allocates + memory to store the most cheap index intersection. + + RETURN + FALSE in the case of success + TRUE otherwise +*/ + +static +bool prepare_search_best_index_intersect(PARAM *param, + SEL_TREE *tree, + COMMON_INDEX_INTERSECTION_INFO *common, + PARTIAL_INDEX_INTERSECTION_INFO *init, + double cutoff_cost) +{ + uint i; + double cost; + INDEX_SCAN_INFO **index_scan; + INDEX_SCAN_INFO **scan_ptr; + INDEX_SCAN_INFO *cpk_scan= NULL; + TABLE *table= param->table; + uint n_index_scans= tree->index_scans_end - tree->index_scans; + + if (!n_index_scans) + return 1; + + bzero(init, sizeof(PARTIAL_INDEX_INTERSECTION_INFO)); + init->common_info= common; + init->cost= cutoff_cost+2*0.01; + + common->param= param; + common->key_size= table->file->ref_length; + common->compare_factor= TIME_FOR_COMPARE_ROWID; + common->max_memory_size= param->thd->variables.sortbuff_size; + common->cutoff_cost= cutoff_cost; + common->cpk_scan= NULL; + common->filtered_out_records= 0; + common->table_cardinality= + get_table_cardinality_for_index_intersect(table); + + if (n_index_scans <= 1) + return TRUE; + + for (i=0, index_scan= tree->index_scans; i < n_index_scans; i++, index_scan++) + { + if ((*index_scan)->keynr == table->s->primary_key && + table->file->primary_key_is_clustered()) + { + common->cpk_scan= cpk_scan= *index_scan; + break; + } + } + + i= n_index_scans - test(cpk_scan != NULL) + 1; + + if (!(common->search_scans = + (INDEX_SCAN_INFO **) alloc_root (param->mem_root, + sizeof(INDEX_SCAN_INFO *) * i))) + return TRUE; + bzero(common->search_scans, sizeof(INDEX_SCAN_INFO *) * i); + + INDEX_SCAN_INFO **selected_index_scans= common->search_scans; + + for (i=0, index_scan= tree->index_scans; i < n_index_scans; i++, index_scan++) + { + uint used_key_parts= (*index_scan)->used_key_parts; + KEY *key_info= (*index_scan)->key_info; + + if (*index_scan == cpk_scan) + continue; + if (cpk_scan && cpk_scan->used_key_parts == used_key_parts && + same_index_prefix(cpk_scan->key_info, key_info, used_key_parts)) + continue; + + cost= get_index_only_read_time(param, (*index_scan)->records, + (*index_scan)->keynr); + if (cost >= cutoff_cost) + continue; + + for (scan_ptr= selected_index_scans; *scan_ptr ; scan_ptr++) + { + if ((*scan_ptr)->used_key_parts == used_key_parts && + same_index_prefix((*scan_ptr)->key_info, key_info, used_key_parts)) + break; + } + if (!*scan_ptr || cost < (*scan_ptr)->index_read_cost) + { + (*index_scan)->index_read_cost= cost; + *scan_ptr= *index_scan; + } + } + + ha_rows records_in_scans= 0; + + for (scan_ptr=selected_index_scans, i= 0; *scan_ptr; scan_ptr++, i++) + { + if (create_fields_bitmap(param, &(*scan_ptr)->used_fields)) + return TRUE; + records_in_scans+= (*scan_ptr)->records; + } + + if (cpk_scan && create_fields_bitmap(param, &cpk_scan->used_fields)) + return TRUE; + + if (!(common->n_search_scans= i)) + return TRUE; + + common->best_uses_cpk= FALSE; + common->best_cost= cutoff_cost + 0.01; + common->best_length= 0; + + if (!(common->best_intersect= + (INDEX_SCAN_INFO **) alloc_root (param->mem_root, + sizeof(INDEX_SCAN_INFO *) * i))) + return TRUE; + + uint calc_cost_buff_size= + Unique::get_cost_calc_buff_size(records_in_scans, + common->key_size, + common->max_memory_size); + if (!(common->buff_elems= (uint *) alloc_root(param->mem_root, + calc_cost_buff_size))) + return TRUE; + + my_qsort(selected_index_scans, i, sizeof(INDEX_SCAN_INFO *), + (qsort_cmp) cmp_intersect_index_scan); + + return FALSE; +} + + +static inline +void set_field_bitmap_for_index_prefix(MY_BITMAP *field_bitmap, + KEY_PART_INFO *key_part, + uint used_key_parts) +{ + bitmap_clear_all(field_bitmap); + for (KEY_PART_INFO *key_part_end= key_part+used_key_parts; + key_part < key_part_end; key_part++) + { + bitmap_set_bit(field_bitmap, key_part->fieldnr-1); + } +} + +/* + Estimate the number of records selected by an extension a partial intersection + + SYNOPSIS + records_in_index_intersect_extension() + curr partial intersection plan to be extended + ext_index_scan the evaluated extension of this partial plan + + NOTES + The function figures out how many records can be expected if the + index scans from curr is intersected with ext_index_scan + + RETURN + The expected number of rows in the extended index intersection +*/ + +static +ha_rows records_in_index_intersect_extension(PARTIAL_INDEX_INTERSECTION_INFO *curr, + INDEX_SCAN_INFO *ext_index_scan) +{ + KEY *key_info= ext_index_scan->key_info; + KEY_PART_INFO* key_part= key_info->key_part; + KEY_PART_INFO* key_part_end= key_part+ext_index_scan->used_key_parts; + MY_BITMAP *used_fields= &ext_index_scan->used_fields; + + if (!curr->length) + { + set_field_bitmap_for_index_prefix(used_fields, key_part, + ext_index_scan->used_key_parts); + return ext_index_scan->records; + } + else + { + bool better_selectivity= FALSE; + ha_rows table_cardinality= curr->common_info->table_cardinality; + ha_rows records= curr->records; + bitmap_copy(used_fields, curr->intersect_fields); + records= (double) records / table_cardinality * ext_index_scan->records; + set_if_bigger(records, 1); + for (uint i= 0 ; key_part < key_part_end; i++, key_part++) + { + if (bitmap_is_set(used_fields, key_part->fieldnr-1)) + { + ulong *rec_per_key= key_info->rec_per_key+i; + ulong f1= rec_per_key[0] ? rec_per_key[0] : 1; + ulong f2= rec_per_key[1] ? rec_per_key[1] : 1; + records= (double) records / f2 * f1; + } + else + { + better_selectivity= TRUE; + bitmap_set_bit(used_fields, key_part->fieldnr-1); + } + } + return !better_selectivity ? curr->records+1 : + !records ? 1 : records; + } +} + + +static inline +double get_unique_intersect_cost(COMMON_INDEX_INTERSECTION_INFO *common, + uint length, ha_rows records_in_scans, + ha_rows filtered_out_records, + ha_rows last_index_records, + bool *in_memory, + double *in_memory_cost) +{ + double cost; + if (length > 1 && *in_memory) + { + ha_rows records_in_first_scan= common->search_scans[0]->records; + ha_rows elems_in_tree= records_in_first_scan-filtered_out_records; + *in_memory_cost+= Unique::get_search_cost(elems_in_tree, + common->compare_factor) * + last_index_records; + cost= *in_memory_cost; + } + else + { + ha_rows records_to_intersect= records_in_scans-filtered_out_records; + cost= Unique::get_use_cost(common->buff_elems, + records_to_intersect, + common->key_size, + common->max_memory_size, + common->compare_factor, + TRUE, in_memory); + if (in_memory) + *in_memory_cost= cost; + } + return cost; +} + + +static inline +double get_cpk_filter_cost(INDEX_SCAN_INFO *index_scan, + INDEX_SCAN_INFO *cpk_scan, + double compare_factor) +{ + return log((double) cpk_scan->range_count) / (compare_factor * M_LN2) * + index_scan->records; +} + + +/* + Check whether a patial index intersection plan can be extended + + SYNOPSIS + check_index_intersect_extension() + curr partial intersection plan to be extended + ext_index_scan a possible extension of this plan to be checked + next OUT the structure to be filled for the extended plan + + NOTES + The function checks whether it makes sense to extend the index + intersection plan adding the index ext_index_scan, and, if this + the case, the function fills in the structure fir the extended plan. + + RETURN + TRUE if the given plan makes to extend + FALSE otherwise +*/ + +static +bool check_index_intersect_extension(PARTIAL_INDEX_INTERSECTION_INFO *curr, + INDEX_SCAN_INFO *ext_index_scan, + PARTIAL_INDEX_INTERSECTION_INFO *next) +{ + ha_rows records; + ha_rows records2; + ha_rows records_in_scans; + double cost; + ha_rows filtered_out_records= 0; + ha_rows index_scan_records= ext_index_scan->records; + COMMON_INDEX_INTERSECTION_INFO *common_info= curr->common_info; + INDEX_SCAN_INFO *cpk_scan= common_info->cpk_scan; + double cutoff_cost= common_info->cutoff_cost; + uint compare_factor= common_info->compare_factor; + uint idx= curr->length; + bool with_cpk_filter= curr->with_cpk_filter; + + if (with_cpk_filter) + filtered_out_records= common_info->filtered_out_records; + + next->index_read_cost= curr->index_read_cost+ext_index_scan->index_read_cost; + if (next->index_read_cost > cutoff_cost) + return FALSE; + + records_in_scans= curr->records_in_scans + index_scan_records; + next->in_memory= curr->in_memory; + + records= records_in_index_intersect_extension(curr, ext_index_scan); + if (idx && records > curr->records) + return FALSE; + + next->records= records; + next->intersect_fields= &ext_index_scan->used_fields; + + cost= get_unique_intersect_cost(common_info, idx+1, records_in_scans, + filtered_out_records, index_scan_records, + &next->in_memory, &next->in_memory_cost); + + if (idx == 0 && cpk_scan) + { + next->length= 1; + records2= records_in_index_intersect_extension(next, cpk_scan); + next->length= 0; + if (records2 < records) + filtered_out_records= records-records2; + + common_info->filter_cost= get_cpk_filter_cost(ext_index_scan, cpk_scan, + compare_factor); + common_info->filtered_out_records= filtered_out_records; + } + + next->records_in_scans= records_in_scans; + next->with_cpk_filter= with_cpk_filter; + + if (!with_cpk_filter && common_info->filtered_out_records) + { + double cost2; + bool in_memory_save= next->in_memory; + if (!idx) + { + next->length= curr->length+1; + records2= records_in_index_intersect_extension(next, cpk_scan); + next->length= curr->length; + } + cost2= get_unique_intersect_cost(common_info, idx+1, records_in_scans, + filtered_out_records, index_scan_records, + &next->in_memory, &next->in_memory_cost); + cost2+= common_info->filter_cost; + if (cost2 < cost) + { + cost= cost2; + records= records2; + next->with_cpk_filter= TRUE; + *next->intersect_fields= cpk_scan->used_fields; + } + else + next->in_memory= in_memory_save; + } + + cost+= next->index_read_cost; + if (cost >= cutoff_cost) + return FALSE; + + next->records= records; + + cost+= get_sweep_read_cost(common_info->param, records); + + next->cost= cost; + next->length= curr->length+1; + + return TRUE; +} + + +/* + Search for the cheapest extensions of range scans used to access a table + + SYNOPSIS + find_index_intersect_best_extension() + curr partial intersection to evaluate all possible extension for + + NOTES + The function tries to extend the partial plan curr in all possible ways + to look for a cheapest index intersection whose cost less than the + cut off value set in curr->common_info.cutoff_cost. +*/ + +static +void find_index_intersect_best_extension(PARTIAL_INDEX_INTERSECTION_INFO *curr) +{ + PARTIAL_INDEX_INTERSECTION_INFO next; + COMMON_INDEX_INTERSECTION_INFO *common_info= curr->common_info; + INDEX_SCAN_INFO **index_scans= common_info->search_scans; + uint idx= curr->length; + INDEX_SCAN_INFO **rem_first_index_scan_ptr= &index_scans[idx]; + double cost= curr->cost; + + if (cost < common_info->best_cost) + { + common_info->best_cost= cost; + common_info->best_length= curr->length; + common_info->best_records= curr->records; + common_info->best_uses_cpk= curr->with_cpk_filter; + uint sz= sizeof(INDEX_SCAN_INFO *) * curr->length; + memcpy(common_info->best_intersect, common_info->search_scans, sz); + common_info->cutoff_cost= cost; + } + + if (!(*rem_first_index_scan_ptr)) + return; + + next.common_info= common_info; + + INDEX_SCAN_INFO *rem_first_index_scan= *rem_first_index_scan_ptr; + for (INDEX_SCAN_INFO **index_scan_ptr= rem_first_index_scan_ptr; + *index_scan_ptr; index_scan_ptr++) + { + *rem_first_index_scan_ptr= *index_scan_ptr; + *index_scan_ptr= rem_first_index_scan; + if (check_index_intersect_extension(curr, *rem_first_index_scan_ptr, &next)) + find_index_intersect_best_extension(&next); + *index_scan_ptr= *rem_first_index_scan_ptr; + *rem_first_index_scan_ptr= rem_first_index_scan; + } +} + + +/* + Get the plan of the best intersection of range scans used to access a table + + SYNOPSIS + get_best_index_intersect() + param common info about index ranges + tree tree of ranges for indexes than can be intersected + read_time cut off value for the evaluated plans + + NOTES + The function looks for the cheapest index intersection of the range + scans to access a table. The info about the ranges for all indexes + is provided by the range optimizer and is passed through the + parameters param and tree. Any plan whose cost is greater than read_time + is rejected. + After the best index intersection is found the function constructs + the structure that manages the execution by the chosen plan. + + RETURN + Pointer to the generated execution structure if a success, + 0 - otherwise. +*/ + static TRP_INDEX_INTERSECT *get_best_index_intersect(PARAM *param, SEL_TREE *tree, double read_time) { uint i; - uint unique_calc_buff_size; + uint count; TRP_RANGE **cur_range; TRP_RANGE **range_scans; + INDEX_SCAN_INFO *index_scan; + COMMON_INDEX_INTERSECTION_INFO common; + PARTIAL_INDEX_INTERSECTION_INFO init; TRP_INDEX_INTERSECT *intersect_trp= NULL; - double intersect_cost= 0.0; - ha_rows scan_records= 0; - double selectivity= 1.0; - ha_rows table_records= param->table->file->stats.records; - uint n_index_scans= tree->index_scans_end - tree->index_scans; + TABLE *table= param->table; + DBUG_ENTER("get_best_index_intersect"); - if (!n_index_scans) + if (prepare_search_best_index_intersect(param, tree, &common, &init, + read_time)) DBUG_RETURN(NULL); + find_index_intersect_best_extension(&init); + + if (common.best_length <= 1 && !common.best_uses_cpk) + DBUG_RETURN(NULL); + + if (common.best_uses_cpk) + { + memmove((char *) (common.best_intersect+1), (char *) common.best_intersect, + sizeof(INDEX_SCAN_INFO *) * common.best_length); + common.best_intersect[0]= common.cpk_scan; + common.best_length++; + } + + count= common.best_length; + if (!(range_scans= (TRP_RANGE**)alloc_root(param->mem_root, sizeof(TRP_RANGE *)* - n_index_scans))) + count))) DBUG_RETURN(NULL); - for (i= 0, cur_range= range_scans; i < n_index_scans; i++) + for (i= 0, cur_range= range_scans; i < count; i++) { - struct st_index_scan_info *index_scan= tree->index_scans[i]; + index_scan= common.best_intersect[i]; if ((*cur_range= new (param->mem_root) TRP_RANGE(index_scan->sel_arg, index_scan->idx))) { - TRP_RANGE *trp= *cur_range; + TRP_RANGE *trp= *cur_range; + trp->read_cost= index_scan->index_read_cost; trp->records= index_scan->records; trp->is_ror= FALSE; - trp->read_cost= get_index_only_read_time(param, index_scan->records, - index_scan->keynr); - scan_records+= trp->records; - selectivity*= (double) trp->records/table_records; - intersect_cost+= trp->read_cost; + table->intersect_keys.set_bit(index_scan->keynr); cur_range++; } } - - /* Add Unique operations cost */ - unique_calc_buff_size= - Unique::get_cost_calc_buff_size((ulong)scan_records, - param->table->file->ref_length, - param->thd->variables.sortbuff_size); - if (param->imerge_cost_buff_size < unique_calc_buff_size) + + count= tree->index_scans_end - tree->index_scans; + for (i= 0; i < count; i++) { - if (!(param->imerge_cost_buff= (uint*)alloc_root(param->mem_root, - unique_calc_buff_size))) - DBUG_RETURN(NULL); - param->imerge_cost_buff_size= unique_calc_buff_size; - } - - intersect_cost += - Unique::get_use_cost(param->imerge_cost_buff, scan_records, - param->table->file->ref_length, - param->thd->variables.sortbuff_size); - - intersect_cost += get_sweep_read_cost(param, - (ha_rows) (table_records*selectivity)); - - if (intersect_cost < read_time) - { - if ((intersect_trp= new (param->mem_root)TRP_INDEX_INTERSECT)) + index_scan= tree->index_scans[i]; + if (!table->intersect_keys.is_set(index_scan->keynr)) { - intersect_trp->read_cost= intersect_cost; - intersect_trp->records= (ha_rows) table_records*selectivity; - set_if_bigger(intersect_trp->records, 1); - intersect_trp->range_scans= range_scans; - intersect_trp->range_scans_end= cur_range; - read_time= intersect_cost; + for (uint j= 0; j < common.best_length; j++) + { + INDEX_SCAN_INFO *scan= common.best_intersect[j]; + if (same_index_prefix(index_scan->key_info, scan->key_info, + scan->used_key_parts)) + { + table->intersect_keys.set_bit(index_scan->keynr); + break; + } + } } } + + if ((intersect_trp= new (param->mem_root)TRP_INDEX_INTERSECT)) + { + intersect_trp->read_cost= common.best_cost; + intersect_trp->records= common.best_records; + intersect_trp->range_scans= range_scans; + intersect_trp->range_scans_end= cur_range; + } DBUG_RETURN(intersect_trp); } @@ -5520,7 +6114,7 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, /* Get best covering ROR-intersection. SYNOPSIS - get_best_covering_ror_intersect() + get_best_ntersectcovering_ror_intersect() param Parameter from test_quick_select function. tree SEL_TREE with sets of intervals for different keys. read_time Don't return table read plans with cost > read_time. @@ -5739,6 +6333,8 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, { index_scan->idx= idx; index_scan->keynr= keynr; + index_scan->key_info= ¶m->table->key_info[keynr]; + index_scan->used_key_parts= param->max_key_part+1; index_scan->range_count= param->range_count; index_scan->records= found_records; index_scan->sel_arg= *key; @@ -5838,6 +6434,7 @@ QUICK_SELECT_I *TRP_INDEX_MERGE::make_quick(PARAM *param, return quick_imerge; } + QUICK_SELECT_I *TRP_INDEX_INTERSECT::make_quick(PARAM *param, bool retrieve_full_rows, MEM_ROOT *parent_alloc) @@ -9504,10 +10101,18 @@ int read_keys_and_merge_scans(THD *thd, if (thd->killed) goto err; - /* skip row if it will be retrieved by clustered PK scan */ - if (pk_quick_select && pk_quick_select->row_in_ranges()) - continue; - + if (intersection) + { + if (first_quick && + pk_quick_select && !pk_quick_select->row_in_ranges()) + continue; + } + else + { + /* skip row if it will be retrieved by clustered PK scan */ + if (pk_quick_select && pk_quick_select->row_in_ranges()) + continue; + } cur_quick->file->position(cur_quick->record); if (unique->unique_add((char*)cur_quick->file->ref)) goto err; @@ -9595,23 +10200,12 @@ int QUICK_INDEX_INTERSECT_SELECT::get_next() int result; DBUG_ENTER("QUICK_INDEX_INTERSECT_SELECT::get_next"); - if (doing_pk_scan) - DBUG_RETURN(pk_quick_select->get_next()); - if ((result= read_record.read_record(&read_record)) == -1) { result= HA_ERR_END_OF_FILE; end_read_record(&read_record); free_io_cache(head); /* All rows from Unique have been retrieved, do a clustered PK scan */ - if (pk_quick_select) - { - doing_pk_scan= TRUE; - if ((result= pk_quick_select->init()) || - (result= pk_quick_select->reset())) - DBUG_RETURN(result); - DBUG_RETURN(pk_quick_select->get_next()); - } } DBUG_RETURN(result); @@ -10292,31 +10886,38 @@ bool QUICK_SELECT_DESC::range_reads_after_key(QUICK_RANGE *range_arg) } -void QUICK_RANGE_SELECT::add_info_string(String *str) +void QUICK_SELECT_I::add_key_name(String *str, bool *first) { KEY *key_info= head->key_info + index; + + if (*first) + *first= FALSE; + else + str->append(','); str->append(key_info->name); } + + +void QUICK_RANGE_SELECT::add_info_string(String *str) +{ + bool first= TRUE; + + add_key_name(str, &first); +} void QUICK_INDEX_MERGE_SELECT::add_info_string(String *str) { QUICK_RANGE_SELECT *quick; bool first= TRUE; List_iterator_fast it(quick_selects); + str->append(STRING_WITH_LEN("sort_union(")); while ((quick= it++)) { - if (!first) - str->append(','); - else - first= FALSE; - quick->add_info_string(str); + quick->add_key_name(str, &first); } if (pk_quick_select) - { - str->append(','); - pk_quick_select->add_info_string(str); - } + pk_quick_select->add_key_name(str, &first); str->append(')'); } @@ -10325,19 +10926,13 @@ void QUICK_INDEX_INTERSECT_SELECT::add_info_string(String *str) QUICK_RANGE_SELECT *quick; bool first= TRUE; List_iterator_fast it(quick_selects); + str->append(STRING_WITH_LEN("sort_intersect(")); + if (pk_quick_select) + pk_quick_select->add_key_name(str, &first); while ((quick= it++)) { - if (!first) - str->append(','); - else - first= FALSE; - quick->add_info_string(str); - } - if (pk_quick_select) - { - str->append(','); - pk_quick_select->add_info_string(str); + quick->add_key_name(str, &first); } str->append(')'); } @@ -10347,148 +10942,125 @@ void QUICK_ROR_INTERSECT_SELECT::add_info_string(String *str) bool first= TRUE; QUICK_RANGE_SELECT *quick; List_iterator_fast it(quick_selects); + str->append(STRING_WITH_LEN("intersect(")); while ((quick= it++)) { - KEY *key_info= head->key_info + quick->index; - if (!first) - str->append(','); - else - first= FALSE; - str->append(key_info->name); + quick->add_key_name(str, &first); } if (cpk_quick) - { - KEY *key_info= head->key_info + cpk_quick->index; - str->append(','); - str->append(key_info->name); - } + cpk_quick->add_key_name(str, &first); str->append(')'); } void QUICK_ROR_UNION_SELECT::add_info_string(String *str) { - bool first= TRUE; QUICK_SELECT_I *quick; + bool first= TRUE; List_iterator_fast it(quick_selects); + str->append(STRING_WITH_LEN("union(")); while ((quick= it++)) { - if (!first) - str->append(','); - else + if (first) first= FALSE; + else + str->append(','); quick->add_info_string(str); } str->append(')'); } -void QUICK_RANGE_SELECT::add_keys_and_lengths(String *key_names, - String *used_lengths) +void QUICK_SELECT_I::add_key_and_length(String *key_names, + String *used_lengths, + bool *first) { char buf[64]; uint length; KEY *key_info= head->key_info + index; + + if (*first) + *first= FALSE; + else + { + key_names->append(','); + used_lengths->append(','); + } key_names->append(key_info->name); length= longlong2str(max_used_key_length, buf, 10) - buf; used_lengths->append(buf, length); } -static -void add_keys_and_lengths_of_index_scans(TABLE *head, - List quick_selects, - QUICK_RANGE_SELECT *pk_quick_select, - String *key_names, - String *used_lengths) + +void QUICK_RANGE_SELECT::add_keys_and_lengths(String *key_names, + String *used_lengths) { - char buf[64]; - uint length; bool first= TRUE; - QUICK_RANGE_SELECT *quick; - List_iterator_fast it(quick_selects); - while ((quick= it++)) - { - if (first) - first= FALSE; - else - { - key_names->append(','); - used_lengths->append(','); - } - - KEY *key_info= head->key_info + quick->index; - key_names->append(key_info->name); - length= longlong2str(quick->max_used_key_length, buf, 10) - buf; - used_lengths->append(buf, length); - } - if (pk_quick_select) - { - KEY *key_info= head->key_info + pk_quick_select->index; - key_names->append(','); - key_names->append(key_info->name); - length= longlong2str(pk_quick_select->max_used_key_length, buf, 10) - buf; - used_lengths->append(','); - used_lengths->append(buf, length); - } + add_key_and_length(key_names, used_lengths, &first); } void QUICK_INDEX_MERGE_SELECT::add_keys_and_lengths(String *key_names, String *used_lengths) { - add_keys_and_lengths_of_index_scans(head, quick_selects, pk_quick_select, - key_names, used_lengths); + QUICK_RANGE_SELECT *quick; + bool first= TRUE; + + List_iterator_fast it(quick_selects); + + while ((quick= it++)) + { + quick->add_key_and_length(key_names, used_lengths, &first); + } + + if (pk_quick_select) + pk_quick_select->add_key_and_length(key_names, used_lengths, &first); } + void QUICK_INDEX_INTERSECT_SELECT::add_keys_and_lengths(String *key_names, String *used_lengths) { - add_keys_and_lengths_of_index_scans(head, quick_selects, pk_quick_select, - key_names, used_lengths); + QUICK_RANGE_SELECT *quick; + bool first= TRUE; + + List_iterator_fast it(quick_selects); + + if (pk_quick_select) + pk_quick_select->add_key_and_length(key_names, used_lengths, &first); + + while ((quick= it++)) + { + quick->add_key_and_length(key_names, used_lengths, &first); + } } void QUICK_ROR_INTERSECT_SELECT::add_keys_and_lengths(String *key_names, String *used_lengths) { - char buf[64]; - uint length; - bool first= TRUE; QUICK_RANGE_SELECT *quick; + bool first= TRUE; + List_iterator_fast it(quick_selects); + while ((quick= it++)) { - KEY *key_info= head->key_info + quick->index; - if (first) - first= FALSE; - else - { - key_names->append(','); - used_lengths->append(','); - } - key_names->append(key_info->name); - length= longlong2str(quick->max_used_key_length, buf, 10) - buf; - used_lengths->append(buf, length); + quick->add_key_and_length(key_names, used_lengths, &first); } - if (cpk_quick) - { - KEY *key_info= head->key_info + cpk_quick->index; - key_names->append(','); - key_names->append(key_info->name); - length= longlong2str(cpk_quick->max_used_key_length, buf, 10) - buf; - used_lengths->append(','); - used_lengths->append(buf, length); - } + cpk_quick->add_key_and_length(key_names, used_lengths, &first); } void QUICK_ROR_UNION_SELECT::add_keys_and_lengths(String *key_names, String *used_lengths) { - bool first= TRUE; QUICK_SELECT_I *quick; + bool first= TRUE; + List_iterator_fast it(quick_selects); + while ((quick= it++)) { if (first) @@ -12634,11 +13206,9 @@ void QUICK_GROUP_MIN_MAX_SELECT::update_max_result() void QUICK_GROUP_MIN_MAX_SELECT::add_keys_and_lengths(String *key_names, String *used_lengths) { - char buf[64]; - uint length; - key_names->append(index_info->name); - length= longlong2str(max_used_key_length, buf, 10) - buf; - used_lengths->append(buf, length); + bool first= TRUE; + + add_key_and_length(key_names, used_lengths, &first); } diff --git a/sql/opt_range.h b/sql/opt_range.h index 0be082e4c9a..b82cd3f2915 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -306,6 +306,10 @@ public: Save ROWID of last retrieved row in file->ref. This used in ROR-merging. */ virtual void save_last_pos(){}; + + void add_key_and_length(String *key_names, + String *used_lengths, + bool *first); /* Append comma-separated list of keys this quick select uses to key_names; @@ -315,13 +319,15 @@ public: virtual void add_keys_and_lengths(String *key_names, String *used_lengths)=0; + void add_key_name(String *str, bool *first); + /* Append text representation of quick select structure (what and how is merged) to str. The result is added to "Extra" field in EXPLAIN output. This function is implemented only by quick selects that merge other quick selects output and/or can produce output suitable for merging. */ - virtual void add_info_string(String *str) {}; + virtual void add_info_string(String *str) {} /* Return 1 if any index used by this quick select uses field which is marked in passed bitmap. diff --git a/sql/sql_class.h b/sql/sql_class.h index 8d27e09ac71..bde632a87e2 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2966,6 +2966,7 @@ class Unique :public Sql_alloc IO_CACHE file; TREE tree; uchar *record_pointers; + ulong filtered_out_elems; bool flush(); uint size; uint full_size; @@ -2991,8 +2992,15 @@ public: void close_for_expansion() { tree.flag= TREE_ONLY_DUPS; } bool get(TABLE *table); + + inline static double get_search_cost(uint tree_elems, uint compare_factor) + { + return log((double) tree_elems) / (compare_factor * M_LN2); + } + static double get_use_cost(uint *buffer, uint nkeys, uint key_size, - ulonglong max_in_memory_size); + ulonglong max_in_memory_size, uint compare_factor, + bool intersect_fl, bool *in_memory); inline static int get_cost_calc_buff_size(ulong nkeys, uint key_size, ulonglong max_in_memory_size) { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d1901b48452..5b0711b5e92 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2684,6 +2684,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds, goto error; } table->quick_keys.clear_all(); + table->intersect_keys.clear_all(); table->reginfo.join_tab=s; table->reginfo.not_exists_optimize=0; bzero((char*) table->const_key_parts, sizeof(key_part_map)*table->s->keys); @@ -6369,8 +6370,10 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) used_tables|=current_map; if (tab->type == JT_REF && tab->quick && - (uint) tab->ref.key == tab->quick->index && - tab->ref.key_length < tab->quick->max_used_key_length) + (((uint) tab->ref.key == tab->quick->index && + tab->ref.key_length < tab->quick->max_used_key_length) || + (!tab->table->intersect_keys.is_clear_all() && + tab->table->intersect_keys.is_set(tab->ref.key)))) { /* Range uses longer key; Use this instead of ref on key */ tab->type=JT_ALL; @@ -10173,6 +10176,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, table->quick_keys.init(); table->covering_keys.init(); table->merge_keys.init(); + table->intersect_keys.init(); table->keys_in_use_for_query.init(); table->s= share; @@ -14223,6 +14227,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, select->cleanup(); // filesort did select tab->select= 0; table->quick_keys.clear_all(); // as far as we cleanup select->quick + table->intersect_keys.clear_all(); table->sort.io_cache= tablesort_result_cache; } tab->select_cond=0; diff --git a/sql/table.h b/sql/table.h index d0836bf5b78..a10bca20605 100644 --- a/sql/table.h +++ b/sql/table.h @@ -682,7 +682,7 @@ struct st_table { needed by the query without reading the row. */ key_map covering_keys; - key_map quick_keys, merge_keys; + key_map quick_keys, merge_keys,intersect_keys; /* A set of keys that can be used in the query that references this table. diff --git a/sql/uniques.cc b/sql/uniques.cc index 30830059995..98517a7494d 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -64,6 +64,8 @@ int unique_intersect_write_to_ptrs(uchar* key, element_count count, Unique *uniq memcpy(unique->record_pointers, key, unique->size); unique->record_pointers+=unique->size; } + else + unique->filtered_out_elems++; return 0; } @@ -144,7 +146,8 @@ inline double log2_n_fact(double x) */ static double get_merge_buffers_cost(uint *buff_elems, uint elem_size, - uint *first, uint *last) + uint *first, uint *last, + uint compare_factor) { uint total_buf_elems= 0; for (uint *pbuf= first; pbuf <= last; pbuf++) @@ -155,7 +158,7 @@ static double get_merge_buffers_cost(uint *buff_elems, uint elem_size, /* Using log2(n)=log(n)/log(2) formula */ return 2*((double)total_buf_elems*elem_size) / IO_SIZE + - total_buf_elems*log((double) n_buffers) / (TIME_FOR_COMPARE_ROWID * M_LN2); + total_buf_elems*log((double) n_buffers) / (compare_factor * M_LN2); } @@ -188,7 +191,8 @@ static double get_merge_buffers_cost(uint *buff_elems, uint elem_size, static double get_merge_many_buffs_cost(uint *buffer, uint maxbuffer, uint max_n_elems, - uint last_n_elems, int elem_size) + uint last_n_elems, int elem_size, + uint compare_factor) { register int i; double total_cost= 0.0; @@ -215,19 +219,22 @@ static double get_merge_many_buffs_cost(uint *buffer, { total_cost+=get_merge_buffers_cost(buff_elems, elem_size, buff_elems + i, - buff_elems + i + MERGEBUFF-1); + buff_elems + i + MERGEBUFF-1, + compare_factor); lastbuff++; } total_cost+=get_merge_buffers_cost(buff_elems, elem_size, buff_elems + i, - buff_elems + maxbuffer); + buff_elems + maxbuffer, + compare_factor); maxbuffer= lastbuff; } } /* Simulate final merge_buff call. */ total_cost += get_merge_buffers_cost(buff_elems, elem_size, - buff_elems, buff_elems + maxbuffer); + buff_elems, buff_elems + maxbuffer, + compare_factor); return total_cost; } @@ -242,7 +249,11 @@ static double get_merge_many_buffs_cost(uint *buffer, to get # bytes needed. nkeys #of elements in Unique key_size size of each elements in bytes - max_in_memory_size amount of memory Unique will be allowed to use + max_in_memory_size amount of memory Unique will be allowed to use + compare_factor used to calculate cost of one comparison + write_fl if the result must be saved written to disk + in_memory_elems OUT estimate of the number of elements in memory + if disk is not used RETURN Cost in disk seeks. @@ -280,7 +291,9 @@ static double get_merge_many_buffs_cost(uint *buffer, */ double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size, - ulonglong max_in_memory_size) + ulonglong max_in_memory_size, + uint compare_factor, + bool intersect_fl, bool *in_memory) { ulong max_elements_in_tree; ulong last_tree_elems; @@ -297,16 +310,15 @@ double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size, result= 2*log2_n_fact(last_tree_elems + 1.0); if (n_full_trees) result+= n_full_trees * log2_n_fact(max_elements_in_tree + 1.0); -#if 1 - result /= TIME_FOR_COMPARE_ROWID; -#else - result /= TIME_FOR_COMPARE_ROWID * 10; -#endif + result /= compare_factor; DBUG_PRINT("info",("unique trees sizes: %u=%u*%lu + %lu", nkeys, n_full_trees, n_full_trees?max_elements_in_tree:0, last_tree_elems)); + if (in_memory) + *in_memory= !n_full_trees; + if (!n_full_trees) return result; @@ -320,12 +332,12 @@ double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size, result += DISK_SEEK_BASE_COST * ceil(((double) key_size)*last_tree_elems / IO_SIZE); /* Cost of merge */ + if (intersect_fl) + key_size+= sizeof(element_count); double merge_cost= get_merge_many_buffs_cost(buffer, n_full_trees, max_elements_in_tree, - last_tree_elems, key_size); - if (merge_cost < 0.0) - return merge_cost; - + last_tree_elems, key_size, + compare_factor); result += merge_cost; /* Add cost of reading the resulting sequence, assuming there were no @@ -614,8 +626,10 @@ bool Unique::get(TABLE *table) tree_walk_action action= min_dupl_count ? (tree_walk_action) unique_intersect_write_to_ptrs : (tree_walk_action) unique_write_to_ptrs; + filtered_out_elems= 0; (void) tree_walk(&tree, action, this, left_root_right); + table->sort.found_records-= filtered_out_elems; return 0; } } @@ -686,3 +700,5 @@ err: outfile->end_of_file=save_pos; return error; } + + diff --git a/sql/unireg.h b/sql/unireg.h index 88a5ca5c12f..b3bf44173e7 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -89,7 +89,7 @@ #define MAX_SELECT_NESTING (sizeof(nesting_map)*8-1) #define MAX_SORT_MEMORY (2048*1024-MALLOC_OVERHEAD) -#define MIN_SORT_MEMORY (32*1024-MALLOC_OVERHEAD) +#define MIN_SORT_MEMORY (1024-MALLOC_OVERHEAD) /* Memory allocated when parsing a statement / saving a statement */ #define MEM_ROOT_BLOCK_SIZE 8192 From e13406b29b4962579bb0bf906d42eccd516675ff Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 3 Dec 2010 20:26:15 -0800 Subject: [PATCH 11/33] Changed the queries of index_intersect.test to ensure platform independent execution plans. Fixed a bug in Unique::unique_add that caused a crash for a query from index_intersect_innodb on some platforms. Fixed two bugs in opt_range.cc that led to the choice of not the cheapest plans for index intersections. --- mysql-test/r/index_intersect.result | 665 ++++++++++-------- mysql-test/r/index_intersect_innodb.result | 549 +++++++++------ mysql-test/suite/innodb/r/innodb_mysql.result | 2 - mysql-test/suite/pbxt/r/subselect.result | 4 - mysql-test/t/index_intersect.test | 103 ++- sql/opt_range.cc | 9 +- sql/sql_class.h | 3 +- 7 files changed, 759 insertions(+), 576 deletions(-) diff --git a/mysql-test/r/index_intersect.result b/mysql-test/r/index_intersect.result index 1a89fe897e7..1bae4a07168 100644 --- a/mysql-test/r/index_intersect.result +++ b/mysql-test/r/index_intersect.result @@ -51,9 +51,9 @@ COUNT(*) SELECT COUNT(*) FROM City WHERE Population > 1000000; COUNT(*) 237 -SELECT COUNT(*) FROM City WHERE Population > 500000; +SELECT COUNT(*) FROM City WHERE Population > 1500000; COUNT(*) -539 +129 SELECT COUNT(*) FROM City WHERE Population > 300000; COUNT(*) 1062 @@ -64,12 +64,12 @@ EXPLAIN SELECT * FROM City WHERE Name LIKE 'C%' AND Population > 1000000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Name Population,Name 4,35 NULL 9 Using sort_intersect(Population,Name); Using where +1 SIMPLE City range Population,Name Name,Population 35,4 NULL 9 Using sort_intersect(Name,Population); Using where EXPLAIN SELECT * FROM City WHERE -Name LIKE 'M%' AND Population > 500000; +Name LIKE 'M%' AND Population > 1500000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Name Population,Name 4,35 NULL 21 Using sort_intersect(Population,Name); Using where +1 SIMPLE City range Population,Name Population,Name 4,35 NULL 5 Using sort_intersect(Population,Name); Using where EXPLAIN SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 300000; @@ -121,97 +121,29 @@ ID Name Country Population 3539 Caracas VEN 1975294 3795 Chicago USA 2896016 SELECT * FROM City USE INDEX () -WHERE Name LIKE 'M%' AND Population > 500000; +WHERE Name LIKE 'M%' AND Population > 1500000; ID Name Country Population -77 Mar del Plata ARG 512880 131 Melbourne AUS 2865329 -215 Manaus BRA 1255049 -223 Maceió BRA 786288 653 Madrid ESP 2879052 -658 Málaga ESP 530553 766 Manila PHL 1581082 942 Medan IDN 1843919 -947 Malang IDN 716862 1024 Mumbai (Bombay) IND 10500000 -1042 Madurai IND 977856 -1051 Meerut IND 753778 -1366 Mosul IRQ 879000 1381 Mashhad IRN 1887405 -1465 Milano ITA 1300977 -1810 Montréal CAN 1016376 -1816 Mississauga CAN 608072 -1945 Mudanjiang CHN 570000 2259 Medellín COL 1861265 -2300 Mbuji-Mayi COD 806475 -2440 Monrovia LBR 850000 -2487 Marrakech MAR 621914 -2523 Monterrey MEX 1108499 -2526 Mexicali MEX 764902 -2530 Mérida MEX 703324 -2537 Morelia MEX 619958 -2698 Maputo MOZ 1018938 -2711 Mandalay MMR 885300 -2734 Managua NIC 959000 -2826 Multan PAK 1182441 -2975 Marseille FRA 798430 -3070 Munich [München] DEU 1194560 -3175 Mekka SAU 965700 -3176 Medina SAU 608300 -3214 Mogadishu SOM 997000 -3364 Mersin (Içel) TUR 587212 -3434 Mykolajiv UKR 508000 -3492 Montevideo URY 1236000 3520 Minsk BLR 1674000 -3540 Maracaíbo VEN 1304776 3580 Moscow RUS 8389200 -3810 Memphis USA 650100 -3811 Milwaukee USA 596974 SELECT * FROM City -WHERE Name LIKE 'M%' AND Population > 500000; +WHERE Name LIKE 'M%' AND Population > 1500000; ID Name Country Population -77 Mar del Plata ARG 512880 131 Melbourne AUS 2865329 -215 Manaus BRA 1255049 -223 Maceió BRA 786288 653 Madrid ESP 2879052 -658 Málaga ESP 530553 766 Manila PHL 1581082 942 Medan IDN 1843919 -947 Malang IDN 716862 1024 Mumbai (Bombay) IND 10500000 -1042 Madurai IND 977856 -1051 Meerut IND 753778 -1366 Mosul IRQ 879000 1381 Mashhad IRN 1887405 -1465 Milano ITA 1300977 -1810 Montréal CAN 1016376 -1816 Mississauga CAN 608072 -1945 Mudanjiang CHN 570000 2259 Medellín COL 1861265 -2300 Mbuji-Mayi COD 806475 -2440 Monrovia LBR 850000 -2487 Marrakech MAR 621914 -2523 Monterrey MEX 1108499 -2526 Mexicali MEX 764902 -2530 Mérida MEX 703324 -2537 Morelia MEX 619958 -2698 Maputo MOZ 1018938 -2711 Mandalay MMR 885300 -2734 Managua NIC 959000 -2826 Multan PAK 1182441 -2975 Marseille FRA 798430 -3070 Munich [München] DEU 1194560 -3175 Mekka SAU 965700 -3176 Medina SAU 608300 -3214 Mogadishu SOM 997000 -3364 Mersin (Içel) TUR 587212 -3434 Mykolajiv UKR 508000 -3492 Montevideo URY 1236000 3520 Minsk BLR 1674000 -3540 Maracaíbo VEN 1304776 3580 Moscow RUS 8389200 -3810 Memphis USA 650100 -3811 Milwaukee USA 596974 SELECT * FROM City USE INDEX () WHERE Name LIKE 'M%' AND Population > 300000; ID Name Country Population @@ -413,33 +345,30 @@ COUNT(*) SELECT COUNT(*) FROM City WHERE Population > 1000000; COUNT(*) 237 -SELECT COUNT(*) FROM City WHERE Population > 700000; -COUNT(*) -358 SELECT COUNT(*) FROM City WHERE Population > 500000; COUNT(*) 539 SELECT COUNT(*) FROM City WHERE Country LIKE 'C%'; COUNT(*) 551 -SELECT COUNT(*) FROM City WHERE Country LIKE 'L%'; +SELECT COUNT(*) FROM City WHERE Country LIKE 'B%'; COUNT(*) -29 +339 EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Country,Name Population,Name 4,35 NULL 9 Using sort_intersect(Population,Name); Using where +1 SIMPLE City range Population,Country,Name Name,Population 35,4 NULL 9 Using sort_intersect(Name,Population); Using where EXPLAIN SELECT * FROM City -WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'L%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Country,Name Country 3 NULL 28 Using where +1 SIMPLE City range Population,Country,Name Population,Country 4,3 NULL 19 Using sort_intersect(Population,Country); Using where EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Country,Name Country,Name 3,35 NULL 29 Using sort_intersect(Country,Name); Using where +1 SIMPLE City range Population,Country,Name Name 35 NULL 225 Using where SELECT * FROM City USE INDEX () WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; ID Name Country Population @@ -451,13 +380,15 @@ ID Name Country Population 1810 Montréal CAN 1016376 2259 Medellín COL 1861265 SELECT * FROM City USE INDEX () -WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; ID Name Country Population -2516 Guadalajara MEX 1647720 +217 Guarulhos BRA 1095874 +218 Goiânia BRA 1056330 SELECT * FROM City -WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; ID Name Country Population -2516 Guadalajara MEX 1647720 +217 Guarulhos BRA 1095874 +218 Goiânia BRA 1056330 SELECT * FROM City USE INDEX () WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; ID Name Country Population @@ -472,23 +403,26 @@ ID Name Country Population SELECT * FROM City WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; ID Name Country Population -1895 Harbin CHN 4289800 -1905 Hangzhou CHN 2190500 1914 Guiyang CHN 1465200 -1916 Hefei CHN 1369100 -1927 Hohhot CHN 916700 1928 Handan CHN 840000 -1937 Huainan CHN 700000 +1905 Hangzhou CHN 2190500 +1895 Harbin CHN 4289800 +1916 Hefei CHN 1369100 1950 Hegang CHN 520000 -SELECT COUNT(*) FROM City WHERE ID BETWEEN 500 AND 999; +1927 Hohhot CHN 916700 +1937 Huainan CHN 700000 +SELECT COUNT(*) FROM City WHERE ID BETWEEN 501 AND 1000; COUNT(*) 500 -SELECT COUNT(*) FROM City WHERE ID BETWEEN 3500 AND 3999; +SELECT COUNT(*) FROM City WHERE ID BETWEEN 1 AND 500; COUNT(*) 500 -SELECT COUNT(*) FROM City WHERE ID BETWEEN 1 AND 1000; +SELECT COUNT(*) FROM City WHERE ID BETWEEN 2001 AND 2500; COUNT(*) -1000 +500 +SELECT COUNT(*) FROM City WHERE ID BETWEEN 3701 AND 4000; +COUNT(*) +300 SELECT COUNT(*) FROM City WHERE Population > 700000; COUNT(*) 358 @@ -498,79 +432,110 @@ COUNT(*) SELECT COUNT(*) FROM City WHERE Population > 300000; COUNT(*) 1062 +SELECT COUNT(*) FROM City WHERE Population > 600000; +COUNT(*) +428 SELECT COUNT(*) FROM City WHERE Country LIKE 'C%'; COUNT(*) 551 SELECT COUNT(*) FROM City WHERE Country LIKE 'A%'; COUNT(*) 107 +SELECT COUNT(*) FROM City WHERE Country LIKE 'L%'; +COUNT(*) +29 SELECT COUNT(*) FROM City WHERE Country BETWEEN 'S' AND 'Z'; COUNT(*) 682 EXPLAIN SELECT * FROM City -WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%'; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Country,Population 4,3,4 NULL 5 Using sort_intersect(PRIMARY,Country,Population); Using where -EXPLAIN -SELECT * FROM City -WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country Population,Country 4,3 NULL 6 Using sort_intersect(Population,Country); Using where -EXPLAIN -SELECT * FROM City -WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%'; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country Country,PRIMARY 3,4 NULL 65 Using sort_intersect(Country,PRIMARY); Using where -EXPLAIN -SELECT * FROM City -WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000 -AND Country BETWEEN 'S' AND 'Z'; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Population 4,4 NULL 44 Using sort_intersect(PRIMARY,Population); Using where -EXPLAIN -SELECT * FROM City -WHERE ID BETWEEN 1 AND 1000 AND Population > 700000 -AND Country BETWEEN 'S' AND 'Z' ; +WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL 359 Using where -SELECT * FROM City USE INDEX () -WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%'; -ID Name Country Population -554 Santiago de Chile CHL 4703954 +EXPLAIN SELECT * FROM City -WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%'; -ID Name Country Population -554 Santiago de Chile CHL 4703954 -SELECT * FROM City USE INDEX () -WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; -ID Name Country Population -SELECT * FROM City -WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; -ID Name Country Population -SELECT * FROM City USE INDEX () -WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%'; -ID Name Country Population -554 Santiago de Chile CHL 4703954 -555 Puente Alto CHL 386236 -556 Viña del Mar CHL 312493 -584 San José CRI 339131 +WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country Country,Population 3,4 NULL 6 Using sort_intersect(Country,Population); Using where +EXPLAIN SELECT * FROM City -WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%'; +WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'L%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country Country 3 NULL 28 Using where +EXPLAIN +SELECT * FROM City +WHERE ID BETWEEN 3701 AND 4000 AND Population > 1000000 +AND Country BETWEEN 'S' AND 'Z'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country Population,PRIMARY 4,4 NULL 17 Using sort_intersect(Population,PRIMARY); Using where +EXPLAIN +SELECT * FROM City +WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 +AND Country BETWEEN 'S' AND 'Z' ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL 429 Using where +SELECT * FROM City USE INDEX () +WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; +ID Name Country Population +554 Santiago de Chile CHL 4703954 +SELECT * FROM City +WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; ID Name Country Population 554 Santiago de Chile CHL 4703954 -555 Puente Alto CHL 386236 -556 Viña del Mar CHL 312493 -584 San José CRI 339131 SELECT * FROM City USE INDEX () -WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000 +WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; +ID Name Country Population +1 Kabul AFG 1780000 +56 Luanda AGO 2022000 +69 Buenos Aires ARG 2982146 +70 La Matanza ARG 1266461 +71 Córdoba ARG 1157507 +126 Yerevan ARM 1248700 +130 Sydney AUS 3276207 +131 Melbourne AUS 2865329 +132 Brisbane AUS 1291117 +133 Perth AUS 1096829 +144 Baku AZE 1787800 +SELECT * FROM City +WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; +ID Name Country Population +1 Kabul AFG 1780000 +56 Luanda AGO 2022000 +69 Buenos Aires ARG 2982146 +70 La Matanza ARG 1266461 +71 Córdoba ARG 1157507 +126 Yerevan ARM 1248700 +130 Sydney AUS 3276207 +131 Melbourne AUS 2865329 +132 Brisbane AUS 1291117 +133 Perth AUS 1096829 +144 Baku AZE 1787800 +SELECT * FROM City USE INDEX () +WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'L%'; +ID Name Country Population +2432 Vientiane LAO 531800 +2434 Riga LVA 764328 +2438 Beirut LBN 1100000 +2440 Monrovia LBR 850000 +2441 Tripoli LBY 1682000 +2442 Bengasi LBY 804000 +2447 Vilnius LTU 577969 +2448 Kaunas LTU 412639 +SELECT * FROM City +WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'L%'; +ID Name Country Population +2432 Vientiane LAO 531800 +2438 Beirut LBN 1100000 +2440 Monrovia LBR 850000 +2441 Tripoli LBY 1682000 +2442 Bengasi LBY 804000 +2447 Vilnius LTU 577969 +2448 Kaunas LTU 412639 +2434 Riga LVA 764328 +SELECT * FROM City USE INDEX () +WHERE ID BETWEEN 3701 AND 4000 AND Population > 700000 AND Country BETWEEN 'S' AND 'Z'; ID Name Country Population -3503 Toskent UZB 2117500 -3539 Caracas VEN 1975294 -3540 Maracaíbo VEN 1304776 -3541 Barquisimeto VEN 877239 -3542 Valencia VEN 794246 3769 Ho Chi Minh City VNM 3980000 3770 Hanoi VNM 1410000 3771 Haiphong VNM 783133 @@ -590,14 +555,9 @@ ID Name Country Population 3806 Jacksonville USA 735167 3807 Columbus USA 711470 SELECT * FROM City -WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000 +WHERE ID BETWEEN 3701 AND 4000 AND Population > 700000 AND Country BETWEEN 'S' AND 'Z'; ID Name Country Population -3503 Toskent UZB 2117500 -3539 Caracas VEN 1975294 -3540 Maracaíbo VEN 1304776 -3541 Barquisimeto VEN 877239 -3542 Valencia VEN 794246 3769 Ho Chi Minh City VNM 3980000 3770 Hanoi VNM 1410000 3771 Haiphong VNM 783133 @@ -617,13 +577,145 @@ ID Name Country Population 3806 Jacksonville USA 735167 3807 Columbus USA 711470 SELECT * FROM City USE INDEX () -WHERE ID BETWEEN 1 AND 1000 AND Population > 700000 +WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 AND Country BETWEEN 'S' AND 'Z' ; ID Name Country Population +3048 Stockholm SWE 750348 +3173 Riyadh SAU 3324000 +3174 Jedda SAU 2046300 +3175 Mekka SAU 965700 +3176 Medina SAU 608300 +3197 Pikine SEN 855287 +3198 Dakar SEN 785071 +3207 Freetown SLE 850000 +3208 Singapore SGP 4017733 +3214 Mogadishu SOM 997000 +3224 Omdurman SDN 1271403 +3225 Khartum SDN 947483 +3226 Sharq al-Nil SDN 700887 +3250 Damascus SYR 1347000 +3251 Aleppo SYR 1261983 +3263 Taipei TWN 2641312 +3264 Kaohsiung TWN 1475505 +3265 Taichung TWN 940589 +3266 Tainan TWN 728060 +3305 Dar es Salaam TZA 1747000 +3320 Bangkok THA 6320174 +3349 Tunis TUN 690600 +3357 Istanbul TUR 8787958 +3358 Ankara TUR 3038159 +3359 Izmir TUR 2130359 +3360 Adana TUR 1131198 +3361 Bursa TUR 1095842 +3362 Gaziantep TUR 789056 +3363 Konya TUR 628364 +3425 Kampala UGA 890800 +3426 Kyiv UKR 2624000 +3427 Harkova [Harkiv] UKR 1500000 +3428 Dnipropetrovsk UKR 1103000 +3429 Donetsk UKR 1050000 +3430 Odesa UKR 1011000 +3431 Zaporizzja UKR 848000 +3432 Lviv UKR 788000 +3433 Kryvyi Rig UKR 703000 +3492 Montevideo URY 1236000 +3503 Toskent UZB 2117500 +3539 Caracas VEN 1975294 +3540 Maracaíbo VEN 1304776 +3541 Barquisimeto VEN 877239 +3542 Valencia VEN 794246 +3543 Ciudad Guayana VEN 663713 +3769 Ho Chi Minh City VNM 3980000 +3770 Hanoi VNM 1410000 +3771 Haiphong VNM 783133 +3793 New York USA 8008278 +3794 Los Angeles USA 3694820 +3795 Chicago USA 2896016 +3796 Houston USA 1953631 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3799 San Diego USA 1223400 +3800 Dallas USA 1188580 +3801 San Antonio USA 1144646 +3802 Detroit USA 951270 +3803 San Jose USA 894943 +3804 Indianapolis USA 791926 +3805 San Francisco USA 776733 +3806 Jacksonville USA 735167 +3807 Columbus USA 711470 +3808 Austin USA 656562 +3809 Baltimore USA 651154 +3810 Memphis USA 650100 SELECT * FROM City -WHERE ID BETWEEN 1 AND 1000 AND Population > 700000 +WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 AND Country BETWEEN 'S' AND 'Z' ; ID Name Country Population +3176 Medina SAU 608300 +3363 Konya TUR 628364 +3810 Memphis USA 650100 +3809 Baltimore USA 651154 +3808 Austin USA 656562 +3543 Ciudad Guayana VEN 663713 +3349 Tunis TUN 690600 +3226 Sharq al-Nil SDN 700887 +3433 Kryvyi Rig UKR 703000 +3807 Columbus USA 711470 +3266 Tainan TWN 728060 +3806 Jacksonville USA 735167 +3048 Stockholm SWE 750348 +3805 San Francisco USA 776733 +3771 Haiphong VNM 783133 +3198 Dakar SEN 785071 +3432 Lviv UKR 788000 +3362 Gaziantep TUR 789056 +3804 Indianapolis USA 791926 +3542 Valencia VEN 794246 +3431 Zaporizzja UKR 848000 +3207 Freetown SLE 850000 +3197 Pikine SEN 855287 +3541 Barquisimeto VEN 877239 +3425 Kampala UGA 890800 +3803 San Jose USA 894943 +3265 Taichung TWN 940589 +3225 Khartum SDN 947483 +3802 Detroit USA 951270 +3175 Mekka SAU 965700 +3214 Mogadishu SOM 997000 +3430 Odesa UKR 1011000 +3429 Donetsk UKR 1050000 +3361 Bursa TUR 1095842 +3428 Dnipropetrovsk UKR 1103000 +3360 Adana TUR 1131198 +3801 San Antonio USA 1144646 +3800 Dallas USA 1188580 +3799 San Diego USA 1223400 +3492 Montevideo URY 1236000 +3251 Aleppo SYR 1261983 +3224 Omdurman SDN 1271403 +3540 Maracaíbo VEN 1304776 +3798 Phoenix USA 1321045 +3250 Damascus SYR 1347000 +3770 Hanoi VNM 1410000 +3264 Kaohsiung TWN 1475505 +3427 Harkova [Harkiv] UKR 1500000 +3797 Philadelphia USA 1517550 +3305 Dar es Salaam TZA 1747000 +3796 Houston USA 1953631 +3539 Caracas VEN 1975294 +3174 Jedda SAU 2046300 +3503 Toskent UZB 2117500 +3359 Izmir TUR 2130359 +3426 Kyiv UKR 2624000 +3263 Taipei TWN 2641312 +3795 Chicago USA 2896016 +3358 Ankara TUR 3038159 +3173 Riyadh SAU 3324000 +3794 Los Angeles USA 3694820 +3769 Ho Chi Minh City VNM 3980000 +3208 Singapore SGP 4017733 +3320 Bangkok THA 6320174 +3793 New York USA 8008278 +3357 Istanbul TUR 8787958 SET SESSION sort_buffer_size = 2048; EXPLAIN SELECT * FROM City WHERE @@ -632,17 +724,12 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Population,Name Name,Population 35,4 NULL 9 Using sort_intersect(Name,Population); Using where EXPLAIN SELECT * FROM City WHERE -Name LIKE 'M%' AND Population > 500000; +Name LIKE 'M%' AND Population > 1500000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Name Name 35 NULL 164 Using where -EXPLAIN -SELECT * FROM City -WHERE Name LIKE 'C%' AND Population > 1000000 AND Country LIKE 'C%'; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Country,Name Name,Population 35,4 NULL 9 Using sort_intersect(Name,Population); Using where +1 SIMPLE City range Population,Name Population,Name 4,35 NULL 5 Using sort_intersect(Population,Name); Using where EXPLAIN SELECT * FROM City -WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Population,Country,Name Name 35 NULL 225 Using where EXPLAIN @@ -652,14 +739,15 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Population,Country,Name Name 35 NULL 225 Using where EXPLAIN SELECT * FROM City -WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; +WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range PRIMARY,Population,Country Country,Population 3,4 NULL 6 Using sort_intersect(Country,Population); Using where EXPLAIN SELECT * FROM City -WHERE ID < 1000 AND Population > 700000 AND Country LIKE 'C%'; +WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 +AND Country BETWEEN 'S' AND 'Z'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL 359 Using where +1 SIMPLE City range PRIMARY,Population,Country Population 4 NULL 429 Using where SELECT * FROM City WHERE Name LIKE 'C%' AND Population > 1000000; ID Name Country Population @@ -681,60 +769,22 @@ ID Name Country Population 3539 Caracas VEN 1975294 3795 Chicago USA 2896016 SELECT * FROM City WHERE -Name LIKE 'M%' AND Population > 500000; +Name LIKE 'M%' AND Population > 1500000; ID Name Country Population -223 Maceió BRA 786288 -653 Madrid ESP 2879052 -1042 Madurai IND 977856 -658 Málaga ESP 530553 -947 Malang IDN 716862 -2734 Managua NIC 959000 -215 Manaus BRA 1255049 -2711 Mandalay MMR 885300 -766 Manila PHL 1581082 -2698 Maputo MOZ 1018938 -77 Mar del Plata ARG 512880 -3540 Maracaíbo VEN 1304776 -2487 Marrakech MAR 621914 -2975 Marseille FRA 798430 -1381 Mashhad IRN 1887405 -2300 Mbuji-Mayi COD 806475 -942 Medan IDN 1843919 -2259 Medellín COL 1861265 -3176 Medina SAU 608300 -1051 Meerut IND 753778 -3175 Mekka SAU 965700 131 Melbourne AUS 2865329 -3810 Memphis USA 650100 -2530 Mérida MEX 703324 -3364 Mersin (Içel) TUR 587212 -2526 Mexicali MEX 764902 -1465 Milano ITA 1300977 -3811 Milwaukee USA 596974 -3520 Minsk BLR 1674000 -1816 Mississauga CAN 608072 -3214 Mogadishu SOM 997000 -2440 Monrovia LBR 850000 -2523 Monterrey MEX 1108499 -3492 Montevideo URY 1236000 -1810 Montréal CAN 1016376 -2537 Morelia MEX 619958 -3580 Moscow RUS 8389200 -1366 Mosul IRQ 879000 -1945 Mudanjiang CHN 570000 -2826 Multan PAK 1182441 +653 Madrid ESP 2879052 +766 Manila PHL 1581082 +942 Medan IDN 1843919 1024 Mumbai (Bombay) IND 10500000 -3070 Munich [München] DEU 1194560 -3434 Mykolajiv UKR 508000 -SELECT * FROM City -WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; -ID Name Country Population +1381 Mashhad IRN 1887405 2259 Medellín COL 1861265 -1810 Montréal CAN 1016376 +3520 Minsk BLR 1674000 +3580 Moscow RUS 8389200 SELECT * FROM City -WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'B%'; ID Name Country Population -2516 Guadalajara MEX 1647720 +218 Goiânia BRA 1056330 +217 Guarulhos BRA 1095874 SELECT * FROM City WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; ID Name Country Population @@ -747,36 +797,112 @@ ID Name Country Population 1927 Hohhot CHN 916700 1937 Huainan CHN 700000 SELECT * FROM City -WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; +WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; ID Name Country Population +1 Kabul AFG 1780000 +56 Luanda AGO 2022000 +69 Buenos Aires ARG 2982146 +70 La Matanza ARG 1266461 +71 Córdoba ARG 1157507 +126 Yerevan ARM 1248700 +130 Sydney AUS 3276207 +131 Melbourne AUS 2865329 +132 Brisbane AUS 1291117 +133 Perth AUS 1096829 +144 Baku AZE 1787800 SELECT * FROM City -WHERE ID < 1000 AND Population > 700000 AND Country LIKE 'C%'; +WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 +AND Country BETWEEN 'S' AND 'Z'; ID Name Country Population -554 Santiago de Chile CHL 4703954 +3176 Medina SAU 608300 +3363 Konya TUR 628364 +3810 Memphis USA 650100 +3809 Baltimore USA 651154 +3808 Austin USA 656562 +3543 Ciudad Guayana VEN 663713 +3349 Tunis TUN 690600 +3226 Sharq al-Nil SDN 700887 +3433 Kryvyi Rig UKR 703000 +3807 Columbus USA 711470 +3266 Tainan TWN 728060 +3806 Jacksonville USA 735167 +3048 Stockholm SWE 750348 +3805 San Francisco USA 776733 +3771 Haiphong VNM 783133 +3198 Dakar SEN 785071 +3432 Lviv UKR 788000 +3362 Gaziantep TUR 789056 +3804 Indianapolis USA 791926 +3542 Valencia VEN 794246 +3431 Zaporizzja UKR 848000 +3207 Freetown SLE 850000 +3197 Pikine SEN 855287 +3541 Barquisimeto VEN 877239 +3425 Kampala UGA 890800 +3803 San Jose USA 894943 +3265 Taichung TWN 940589 +3225 Khartum SDN 947483 +3802 Detroit USA 951270 +3175 Mekka SAU 965700 +3214 Mogadishu SOM 997000 +3430 Odesa UKR 1011000 +3429 Donetsk UKR 1050000 +3361 Bursa TUR 1095842 +3428 Dnipropetrovsk UKR 1103000 +3360 Adana TUR 1131198 +3801 San Antonio USA 1144646 +3800 Dallas USA 1188580 +3799 San Diego USA 1223400 +3492 Montevideo URY 1236000 +3251 Aleppo SYR 1261983 +3224 Omdurman SDN 1271403 +3540 Maracaíbo VEN 1304776 +3798 Phoenix USA 1321045 +3250 Damascus SYR 1347000 +3770 Hanoi VNM 1410000 +3264 Kaohsiung TWN 1475505 +3427 Harkova [Harkiv] UKR 1500000 +3797 Philadelphia USA 1517550 +3305 Dar es Salaam TZA 1747000 +3796 Houston USA 1953631 +3539 Caracas VEN 1975294 +3174 Jedda SAU 2046300 +3503 Toskent UZB 2117500 +3359 Izmir TUR 2130359 +3426 Kyiv UKR 2624000 +3263 Taipei TWN 2641312 +3795 Chicago USA 2896016 +3358 Ankara TUR 3038159 +3173 Riyadh SAU 3324000 +3794 Los Angeles USA 3694820 +3769 Ho Chi Minh City VNM 3980000 +3208 Singapore SGP 4017733 +3320 Bangkok THA 6320174 +3793 New York USA 8008278 +3357 Istanbul TUR 8787958 SET SESSION sort_buffer_size = default; DROP INDEX Country ON City; CREATE INDEX CountryID ON City(Country,ID); CREATE INDEX CountryName ON City(Country,Name); EXPLAIN SELECT * FROM City -WHERE Country LIKE 'M%' AND Population > 700000; +WHERE Country LIKE 'M%' AND Population > 1000000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,CountryID,CountryName Population,CountryID 4,3 NULL 23 Using sort_intersect(Population,CountryID); Using where +1 SIMPLE City range Population,CountryID,CountryName Population,CountryID 4,3 NULL 15 Using sort_intersect(Population,CountryID); Using where EXPLAIN SELECT * FROM City -WHERE Country='CHN' AND Population > 1000000; +WHERE Country='CHN' AND Population > 1500000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,CountryID,CountryName CountryID,Population 3,4 NULL 20 Using sort_intersect(CountryID,Population); Using where +1 SIMPLE City range Population,CountryID,CountryName Population,CountryID 4,3 NULL 11 Using sort_intersect(Population,CountryID); Using where EXPLAIN SELECT * FROM City -WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%'; +WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Name,CountryID,CountryName CountryName 38 NULL 13 Using where +1 SIMPLE City range Population,Name,CountryID,CountryName CountryName,Population 38,4 NULL 1 Using sort_intersect(CountryName,Population); Using where SELECT * FROM City USE INDEX () -WHERE Country LIKE 'M%' AND Population > 700000; +WHERE Country LIKE 'M%' AND Population > 1000000; ID Name Country Population 2464 Kuala Lumpur MYS 1297526 -2482 Bamako MLI 809552 2485 Casablanca MAR 2940623 2515 Ciudad de México MEX 8591309 2516 Guadalajara MEX 1647720 @@ -788,46 +914,37 @@ ID Name Country Population 2522 León MEX 1133576 2523 Monterrey MEX 1108499 2524 Zapopan MEX 1002239 +2698 Maputo MOZ 1018938 +2710 Rangoon (Yangon) MMR 3361700 +SELECT * FROM City +WHERE Country LIKE 'M%' AND Population > 700000; +ID Name Country Population +2485 Casablanca MAR 2940623 +2690 Chisinau MDA 719900 +2515 Ciudad de México MEX 8591309 +2516 Guadalajara MEX 1647720 +2517 Ecatepec de Morelos MEX 1620303 +2518 Puebla MEX 1346176 +2519 Nezahualcóyotl MEX 1224924 +2520 Juárez MEX 1217818 +2521 Tijuana MEX 1212232 +2522 León MEX 1133576 +2523 Monterrey MEX 1108499 +2524 Zapopan MEX 1002239 2525 Naucalpan de Juárez MEX 857511 2526 Mexicali MEX 764902 2527 Culiacán MEX 744859 2528 Acapulco de Juárez MEX 721011 2529 Tlalnepantla de Baz MEX 720755 2530 Mérida MEX 703324 -2690 Chisinau MDA 719900 -2696 Ulan Bator MNG 773700 -2698 Maputo MOZ 1018938 -2710 Rangoon (Yangon) MMR 3361700 -2711 Mandalay MMR 885300 -SELECT * FROM City -WHERE Country LIKE 'M%' AND Population > 700000; -ID Name Country Population -2464 Kuala Lumpur MYS 1297526 2482 Bamako MLI 809552 -2485 Casablanca MAR 2940623 -2515 Ciudad de México MEX 8591309 -2516 Guadalajara MEX 1647720 -2517 Ecatepec de Morelos MEX 1620303 -2518 Puebla MEX 1346176 -2519 Nezahualcóyotl MEX 1224924 -2520 Juárez MEX 1217818 -2521 Tijuana MEX 1212232 -2522 León MEX 1133576 -2523 Monterrey MEX 1108499 -2524 Zapopan MEX 1002239 -2525 Naucalpan de Juárez MEX 857511 -2526 Mexicali MEX 764902 -2527 Culiacán MEX 744859 -2528 Acapulco de Juárez MEX 721011 -2529 Tlalnepantla de Baz MEX 720755 -2530 Mérida MEX 703324 -2690 Chisinau MDA 719900 -2696 Ulan Bator MNG 773700 -2698 Maputo MOZ 1018938 2710 Rangoon (Yangon) MMR 3361700 2711 Mandalay MMR 885300 +2696 Ulan Bator MNG 773700 +2698 Maputo MOZ 1018938 +2464 Kuala Lumpur MYS 1297526 SELECT * FROM City USE INDEX () -WHERE Country='CHN' AND Population > 1000000; +WHERE Country='CHN' AND Population > 1500000; ID Name Country Population 1890 Shanghai CHN 9696300 1891 Peking CHN 7472000 @@ -853,19 +970,8 @@ ID Name Country Population 1911 Nanchang CHN 1691600 1912 Fuzhou CHN 1593800 1913 Lanzhou CHN 1565800 -1914 Guiyang CHN 1465200 -1915 Ningbo CHN 1371200 -1916 Hefei CHN 1369100 -1917 Urumt?i [Ürümqi] CHN 1310100 -1918 Anshan CHN 1200000 -1919 Fushun CHN 1200000 -1920 Nanning CHN 1161800 -1921 Zibo CHN 1140000 -1922 Qiqihar CHN 1070000 -1923 Jilin CHN 1040000 -1924 Tangshan CHN 1040000 SELECT * FROM City -WHERE Country='CHN' AND Population > 1000000; +WHERE Country='CHN' AND Population > 1500000; ID Name Country Population 1890 Shanghai CHN 9696300 1891 Peking CHN 7472000 @@ -891,31 +997,20 @@ ID Name Country Population 1911 Nanchang CHN 1691600 1912 Fuzhou CHN 1593800 1913 Lanzhou CHN 1565800 -1914 Guiyang CHN 1465200 -1915 Ningbo CHN 1371200 -1916 Hefei CHN 1369100 -1917 Urumt?i [Ürümqi] CHN 1310100 -1918 Anshan CHN 1200000 -1919 Fushun CHN 1200000 -1920 Nanning CHN 1161800 -1921 Zibo CHN 1140000 -1922 Qiqihar CHN 1070000 -1923 Jilin CHN 1040000 -1924 Tangshan CHN 1040000 SELECT * FROM City USE INDEX () -WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%'; +WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; ID Name Country Population 1892 Chongqing CHN 6351600 1898 Chengdu CHN 3361500 1900 Changchun CHN 2812000 1910 Changsha CHN 1809800 SELECT * FROM City -WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%'; +WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; ID Name Country Population +1892 Chongqing CHN 6351600 +1898 Chengdu CHN 3361500 1900 Changchun CHN 2812000 1910 Changsha CHN 1809800 -1898 Chengdu CHN 3361500 -1892 Chongqing CHN 6351600 DROP DATABASE world; use test; SET SESSION optimizer_switch='index_merge_sort_intersection=on'; diff --git a/mysql-test/r/index_intersect_innodb.result b/mysql-test/r/index_intersect_innodb.result index 89c2e9faee9..fc85846110a 100644 --- a/mysql-test/r/index_intersect_innodb.result +++ b/mysql-test/r/index_intersect_innodb.result @@ -52,9 +52,9 @@ COUNT(*) SELECT COUNT(*) FROM City WHERE Population > 1000000; COUNT(*) 237 -SELECT COUNT(*) FROM City WHERE Population > 500000; +SELECT COUNT(*) FROM City WHERE Population > 1500000; COUNT(*) -539 +129 SELECT COUNT(*) FROM City WHERE Population > 300000; COUNT(*) 1062 @@ -65,17 +65,17 @@ EXPLAIN SELECT * FROM City WHERE Name LIKE 'C%' AND Population > 1000000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Name Name,Population 35,4 NULL 16 Using sort_intersect(Name,Population); Using where +1 SIMPLE City range Population,Name Population,Name 4,35 NULL 16 Using sort_intersect(Population,Name); Using where EXPLAIN SELECT * FROM City WHERE -Name LIKE 'M%' AND Population > 500000; +Name LIKE 'M%' AND Population > 1500000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Name Population,Name 4,35 NULL 40 Using sort_intersect(Population,Name); Using where +1 SIMPLE City range Population,Name Population,Name 4,35 NULL 9 Using sort_intersect(Population,Name); Using where EXPLAIN SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 300000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Name Population,Name 4,35 NULL 79 Using sort_intersect(Population,Name); Using where +1 SIMPLE City range Population,Name Name,Population 35,4 NULL 79 Using sort_intersect(Name,Population); Using where EXPLAIN SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 5000000; @@ -122,97 +122,29 @@ ID Name Country Population 3539 Caracas VEN 1975294 3795 Chicago USA 2896016 SELECT * FROM City USE INDEX () -WHERE Name LIKE 'M%' AND Population > 500000; +WHERE Name LIKE 'M%' AND Population > 1500000; ID Name Country Population -77 Mar del Plata ARG 512880 131 Melbourne AUS 2865329 -215 Manaus BRA 1255049 -223 Maceió BRA 786288 653 Madrid ESP 2879052 -658 Málaga ESP 530553 766 Manila PHL 1581082 942 Medan IDN 1843919 -947 Malang IDN 716862 1024 Mumbai (Bombay) IND 10500000 -1042 Madurai IND 977856 -1051 Meerut IND 753778 -1366 Mosul IRQ 879000 1381 Mashhad IRN 1887405 -1465 Milano ITA 1300977 -1810 Montréal CAN 1016376 -1816 Mississauga CAN 608072 -1945 Mudanjiang CHN 570000 2259 Medellín COL 1861265 -2300 Mbuji-Mayi COD 806475 -2440 Monrovia LBR 850000 -2487 Marrakech MAR 621914 -2523 Monterrey MEX 1108499 -2526 Mexicali MEX 764902 -2530 Mérida MEX 703324 -2537 Morelia MEX 619958 -2698 Maputo MOZ 1018938 -2711 Mandalay MMR 885300 -2734 Managua NIC 959000 -2826 Multan PAK 1182441 -2975 Marseille FRA 798430 -3070 Munich [München] DEU 1194560 -3175 Mekka SAU 965700 -3176 Medina SAU 608300 -3214 Mogadishu SOM 997000 -3364 Mersin (Içel) TUR 587212 -3434 Mykolajiv UKR 508000 -3492 Montevideo URY 1236000 3520 Minsk BLR 1674000 -3540 Maracaíbo VEN 1304776 3580 Moscow RUS 8389200 -3810 Memphis USA 650100 -3811 Milwaukee USA 596974 SELECT * FROM City -WHERE Name LIKE 'M%' AND Population > 500000; +WHERE Name LIKE 'M%' AND Population > 1500000; ID Name Country Population -77 Mar del Plata ARG 512880 131 Melbourne AUS 2865329 -215 Manaus BRA 1255049 -223 Maceió BRA 786288 653 Madrid ESP 2879052 -658 Málaga ESP 530553 766 Manila PHL 1581082 942 Medan IDN 1843919 -947 Malang IDN 716862 1024 Mumbai (Bombay) IND 10500000 -1042 Madurai IND 977856 -1051 Meerut IND 753778 -1366 Mosul IRQ 879000 1381 Mashhad IRN 1887405 -1465 Milano ITA 1300977 -1810 Montréal CAN 1016376 -1816 Mississauga CAN 608072 -1945 Mudanjiang CHN 570000 2259 Medellín COL 1861265 -2300 Mbuji-Mayi COD 806475 -2440 Monrovia LBR 850000 -2487 Marrakech MAR 621914 -2523 Monterrey MEX 1108499 -2526 Mexicali MEX 764902 -2530 Mérida MEX 703324 -2537 Morelia MEX 619958 -2698 Maputo MOZ 1018938 -2711 Mandalay MMR 885300 -2734 Managua NIC 959000 -2826 Multan PAK 1182441 -2975 Marseille FRA 798430 -3070 Munich [München] DEU 1194560 -3175 Mekka SAU 965700 -3176 Medina SAU 608300 -3214 Mogadishu SOM 997000 -3364 Mersin (Içel) TUR 587212 -3434 Mykolajiv UKR 508000 -3492 Montevideo URY 1236000 3520 Minsk BLR 1674000 -3540 Maracaíbo VEN 1304776 3580 Moscow RUS 8389200 -3810 Memphis USA 650100 -3811 Milwaukee USA 596974 SELECT * FROM City USE INDEX () WHERE Name LIKE 'M%' AND Population > 300000; ID Name Country Population @@ -414,18 +346,15 @@ COUNT(*) SELECT COUNT(*) FROM City WHERE Population > 1000000; COUNT(*) 237 -SELECT COUNT(*) FROM City WHERE Population > 700000; -COUNT(*) -358 SELECT COUNT(*) FROM City WHERE Population > 500000; COUNT(*) 539 SELECT COUNT(*) FROM City WHERE Country LIKE 'C%'; COUNT(*) 551 -SELECT COUNT(*) FROM City WHERE Country LIKE 'L%'; +SELECT COUNT(*) FROM City WHERE Country LIKE 'B%'; COUNT(*) -29 +339 EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; @@ -433,14 +362,14 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Population,Country,Name Population,Name,Country 4,35,3 NULL 2 Using sort_intersect(Population,Name,Country); Using where EXPLAIN SELECT * FROM City -WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'L%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Country,Name Country,Population 3,4 NULL 2 Using sort_intersect(Country,Population); Using where +1 SIMPLE City range Population,Country,Name Population,Country,Name 4,3,35 NULL 2 Using sort_intersect(Population,Country,Name); Using where EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Country,Name Population,Country,Name 4,3,35 NULL 7 Using sort_intersect(Population,Country,Name); Using where +1 SIMPLE City range Population,Country,Name Name,Population,Country 35,4,3 NULL 7 Using sort_intersect(Name,Population,Country); Using where SELECT * FROM City USE INDEX () WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; ID Name Country Population @@ -452,13 +381,15 @@ ID Name Country Population 1810 Montréal CAN 1016376 2259 Medellín COL 1861265 SELECT * FROM City USE INDEX () -WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; ID Name Country Population -2516 Guadalajara MEX 1647720 +217 Guarulhos BRA 1095874 +218 Goiânia BRA 1056330 SELECT * FROM City -WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; ID Name Country Population -2516 Guadalajara MEX 1647720 +217 Guarulhos BRA 1095874 +218 Goiânia BRA 1056330 SELECT * FROM City USE INDEX () WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; ID Name Country Population @@ -481,15 +412,18 @@ ID Name Country Population 1928 Handan CHN 840000 1937 Huainan CHN 700000 1950 Hegang CHN 520000 -SELECT COUNT(*) FROM City WHERE ID BETWEEN 500 AND 999; +SELECT COUNT(*) FROM City WHERE ID BETWEEN 501 AND 1000; COUNT(*) 500 -SELECT COUNT(*) FROM City WHERE ID BETWEEN 3500 AND 3999; +SELECT COUNT(*) FROM City WHERE ID BETWEEN 1 AND 500; COUNT(*) 500 -SELECT COUNT(*) FROM City WHERE ID BETWEEN 1 AND 1000; +SELECT COUNT(*) FROM City WHERE ID BETWEEN 2001 AND 2500; COUNT(*) -1000 +500 +SELECT COUNT(*) FROM City WHERE ID BETWEEN 3701 AND 4000; +COUNT(*) +300 SELECT COUNT(*) FROM City WHERE Population > 700000; COUNT(*) 358 @@ -499,79 +433,110 @@ COUNT(*) SELECT COUNT(*) FROM City WHERE Population > 300000; COUNT(*) 1062 +SELECT COUNT(*) FROM City WHERE Population > 600000; +COUNT(*) +428 SELECT COUNT(*) FROM City WHERE Country LIKE 'C%'; COUNT(*) 551 SELECT COUNT(*) FROM City WHERE Country LIKE 'A%'; COUNT(*) 107 +SELECT COUNT(*) FROM City WHERE Country LIKE 'L%'; +COUNT(*) +29 SELECT COUNT(*) FROM City WHERE Country BETWEEN 'S' AND 'Z'; COUNT(*) 682 EXPLAIN SELECT * FROM City -WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%'; +WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Country,Population 4,3,4 NULL 11 Using sort_intersect(PRIMARY,Country,Population); Using where EXPLAIN SELECT * FROM City -WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; +WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Population,Country 4,4,3 NULL 1 Using sort_intersect(PRIMARY,Population,Country); Using where EXPLAIN SELECT * FROM City -WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%'; +WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'L%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Population,Country 4,4,3 NULL 34 Using sort_intersect(PRIMARY,Population,Country); Using where +1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Country 4,3 NULL 10 Using sort_intersect(PRIMARY,Country); Using where EXPLAIN SELECT * FROM City -WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000 +WHERE ID BETWEEN 3701 AND 4000 AND Population > 1000000 AND Country BETWEEN 'S' AND 'Z'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Country,Population 4,3,4 NULL 12 Using sort_intersect(PRIMARY,Country,Population); Using where +1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Country,Population 4,3,4 NULL 2 Using sort_intersect(PRIMARY,Country,Population); Using where EXPLAIN SELECT * FROM City -WHERE ID BETWEEN 1 AND 1000 AND Population > 700000 +WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 AND Country BETWEEN 'S' AND 'Z' ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Country,Population 4,3,4 NULL 21 Using sort_intersect(PRIMARY,Country,Population); Using where +1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Population,Country 4,4,3 NULL 30 Using sort_intersect(PRIMARY,Population,Country); Using where SELECT * FROM City USE INDEX () -WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%'; +WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; ID Name Country Population 554 Santiago de Chile CHL 4703954 SELECT * FROM City -WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%'; +WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; ID Name Country Population 554 Santiago de Chile CHL 4703954 SELECT * FROM City USE INDEX () -WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; +WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; ID Name Country Population +1 Kabul AFG 1780000 +56 Luanda AGO 2022000 +69 Buenos Aires ARG 2982146 +70 La Matanza ARG 1266461 +71 Córdoba ARG 1157507 +126 Yerevan ARM 1248700 +130 Sydney AUS 3276207 +131 Melbourne AUS 2865329 +132 Brisbane AUS 1291117 +133 Perth AUS 1096829 +144 Baku AZE 1787800 SELECT * FROM City -WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; +WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; ID Name Country Population +1 Kabul AFG 1780000 +56 Luanda AGO 2022000 +69 Buenos Aires ARG 2982146 +70 La Matanza ARG 1266461 +71 Córdoba ARG 1157507 +126 Yerevan ARM 1248700 +130 Sydney AUS 3276207 +131 Melbourne AUS 2865329 +132 Brisbane AUS 1291117 +133 Perth AUS 1096829 +144 Baku AZE 1787800 SELECT * FROM City USE INDEX () -WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%'; +WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'L%'; ID Name Country Population -554 Santiago de Chile CHL 4703954 -555 Puente Alto CHL 386236 -556 Viña del Mar CHL 312493 -584 San José CRI 339131 +2432 Vientiane LAO 531800 +2434 Riga LVA 764328 +2438 Beirut LBN 1100000 +2440 Monrovia LBR 850000 +2441 Tripoli LBY 1682000 +2442 Bengasi LBY 804000 +2447 Vilnius LTU 577969 +2448 Kaunas LTU 412639 SELECT * FROM City -WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%'; +WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'L%'; ID Name Country Population -554 Santiago de Chile CHL 4703954 -555 Puente Alto CHL 386236 -556 Viña del Mar CHL 312493 -584 San José CRI 339131 +2432 Vientiane LAO 531800 +2434 Riga LVA 764328 +2438 Beirut LBN 1100000 +2440 Monrovia LBR 850000 +2441 Tripoli LBY 1682000 +2442 Bengasi LBY 804000 +2447 Vilnius LTU 577969 +2448 Kaunas LTU 412639 SELECT * FROM City USE INDEX () -WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000 +WHERE ID BETWEEN 3701 AND 4000 AND Population > 700000 AND Country BETWEEN 'S' AND 'Z'; ID Name Country Population -3503 Toskent UZB 2117500 -3539 Caracas VEN 1975294 -3540 Maracaíbo VEN 1304776 -3541 Barquisimeto VEN 877239 -3542 Valencia VEN 794246 3769 Ho Chi Minh City VNM 3980000 3770 Hanoi VNM 1410000 3771 Haiphong VNM 783133 @@ -591,14 +556,9 @@ ID Name Country Population 3806 Jacksonville USA 735167 3807 Columbus USA 711470 SELECT * FROM City -WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000 +WHERE ID BETWEEN 3701 AND 4000 AND Population > 700000 AND Country BETWEEN 'S' AND 'Z'; ID Name Country Population -3503 Toskent UZB 2117500 -3539 Caracas VEN 1975294 -3540 Maracaíbo VEN 1304776 -3541 Barquisimeto VEN 877239 -3542 Valencia VEN 794246 3769 Ho Chi Minh City VNM 3980000 3770 Hanoi VNM 1410000 3771 Haiphong VNM 783133 @@ -618,13 +578,145 @@ ID Name Country Population 3806 Jacksonville USA 735167 3807 Columbus USA 711470 SELECT * FROM City USE INDEX () -WHERE ID BETWEEN 1 AND 1000 AND Population > 700000 +WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 AND Country BETWEEN 'S' AND 'Z' ; ID Name Country Population +3048 Stockholm SWE 750348 +3173 Riyadh SAU 3324000 +3174 Jedda SAU 2046300 +3175 Mekka SAU 965700 +3176 Medina SAU 608300 +3197 Pikine SEN 855287 +3198 Dakar SEN 785071 +3207 Freetown SLE 850000 +3208 Singapore SGP 4017733 +3214 Mogadishu SOM 997000 +3224 Omdurman SDN 1271403 +3225 Khartum SDN 947483 +3226 Sharq al-Nil SDN 700887 +3250 Damascus SYR 1347000 +3251 Aleppo SYR 1261983 +3263 Taipei TWN 2641312 +3264 Kaohsiung TWN 1475505 +3265 Taichung TWN 940589 +3266 Tainan TWN 728060 +3305 Dar es Salaam TZA 1747000 +3320 Bangkok THA 6320174 +3349 Tunis TUN 690600 +3357 Istanbul TUR 8787958 +3358 Ankara TUR 3038159 +3359 Izmir TUR 2130359 +3360 Adana TUR 1131198 +3361 Bursa TUR 1095842 +3362 Gaziantep TUR 789056 +3363 Konya TUR 628364 +3425 Kampala UGA 890800 +3426 Kyiv UKR 2624000 +3427 Harkova [Harkiv] UKR 1500000 +3428 Dnipropetrovsk UKR 1103000 +3429 Donetsk UKR 1050000 +3430 Odesa UKR 1011000 +3431 Zaporizzja UKR 848000 +3432 Lviv UKR 788000 +3433 Kryvyi Rig UKR 703000 +3492 Montevideo URY 1236000 +3503 Toskent UZB 2117500 +3539 Caracas VEN 1975294 +3540 Maracaíbo VEN 1304776 +3541 Barquisimeto VEN 877239 +3542 Valencia VEN 794246 +3543 Ciudad Guayana VEN 663713 +3769 Ho Chi Minh City VNM 3980000 +3770 Hanoi VNM 1410000 +3771 Haiphong VNM 783133 +3793 New York USA 8008278 +3794 Los Angeles USA 3694820 +3795 Chicago USA 2896016 +3796 Houston USA 1953631 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3799 San Diego USA 1223400 +3800 Dallas USA 1188580 +3801 San Antonio USA 1144646 +3802 Detroit USA 951270 +3803 San Jose USA 894943 +3804 Indianapolis USA 791926 +3805 San Francisco USA 776733 +3806 Jacksonville USA 735167 +3807 Columbus USA 711470 +3808 Austin USA 656562 +3809 Baltimore USA 651154 +3810 Memphis USA 650100 SELECT * FROM City -WHERE ID BETWEEN 1 AND 1000 AND Population > 700000 +WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 AND Country BETWEEN 'S' AND 'Z' ; ID Name Country Population +3048 Stockholm SWE 750348 +3173 Riyadh SAU 3324000 +3174 Jedda SAU 2046300 +3175 Mekka SAU 965700 +3176 Medina SAU 608300 +3197 Pikine SEN 855287 +3198 Dakar SEN 785071 +3207 Freetown SLE 850000 +3208 Singapore SGP 4017733 +3214 Mogadishu SOM 997000 +3224 Omdurman SDN 1271403 +3225 Khartum SDN 947483 +3226 Sharq al-Nil SDN 700887 +3250 Damascus SYR 1347000 +3251 Aleppo SYR 1261983 +3263 Taipei TWN 2641312 +3264 Kaohsiung TWN 1475505 +3265 Taichung TWN 940589 +3266 Tainan TWN 728060 +3305 Dar es Salaam TZA 1747000 +3320 Bangkok THA 6320174 +3349 Tunis TUN 690600 +3357 Istanbul TUR 8787958 +3358 Ankara TUR 3038159 +3359 Izmir TUR 2130359 +3360 Adana TUR 1131198 +3361 Bursa TUR 1095842 +3362 Gaziantep TUR 789056 +3363 Konya TUR 628364 +3425 Kampala UGA 890800 +3426 Kyiv UKR 2624000 +3427 Harkova [Harkiv] UKR 1500000 +3428 Dnipropetrovsk UKR 1103000 +3429 Donetsk UKR 1050000 +3430 Odesa UKR 1011000 +3431 Zaporizzja UKR 848000 +3432 Lviv UKR 788000 +3433 Kryvyi Rig UKR 703000 +3492 Montevideo URY 1236000 +3503 Toskent UZB 2117500 +3539 Caracas VEN 1975294 +3540 Maracaíbo VEN 1304776 +3541 Barquisimeto VEN 877239 +3542 Valencia VEN 794246 +3543 Ciudad Guayana VEN 663713 +3769 Ho Chi Minh City VNM 3980000 +3770 Hanoi VNM 1410000 +3771 Haiphong VNM 783133 +3793 New York USA 8008278 +3794 Los Angeles USA 3694820 +3795 Chicago USA 2896016 +3796 Houston USA 1953631 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3799 San Diego USA 1223400 +3800 Dallas USA 1188580 +3801 San Antonio USA 1144646 +3802 Detroit USA 951270 +3803 San Jose USA 894943 +3804 Indianapolis USA 791926 +3805 San Francisco USA 776733 +3806 Jacksonville USA 735167 +3807 Columbus USA 711470 +3808 Austin USA 656562 +3809 Baltimore USA 651154 +3810 Memphis USA 650100 SET SESSION sort_buffer_size = 2048; EXPLAIN SELECT * FROM City WHERE @@ -633,19 +725,14 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Population,Name Population,Name 4,35 NULL 16 Using sort_intersect(Population,Name); Using where EXPLAIN SELECT * FROM City WHERE -Name LIKE 'M%' AND Population > 500000; +Name LIKE 'M%' AND Population > 1500000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Name Name,Population 35,4 NULL 40 Using sort_intersect(Name,Population); Using where -EXPLAIN -SELECT * FROM City -WHERE Name LIKE 'C%' AND Population > 1000000 AND Country LIKE 'C%'; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Country,Name Population,Name 4,35 NULL 16 Using sort_intersect(Population,Name); Using where +1 SIMPLE City range Population,Name Population,Name 4,35 NULL 9 Using sort_intersect(Population,Name); Using where EXPLAIN SELECT * FROM City -WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Country,Name Population,Name 4,35 NULL 36 Using sort_intersect(Population,Name); Using where +1 SIMPLE City range Population,Country,Name Population,Country,Name 4,3,35 NULL 2 Using sort_intersect(Population,Country,Name); Using where EXPLAIN SELECT * FROM City WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; @@ -653,14 +740,15 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Population,Country,Name Name,Population,Country 35,4,3 NULL 7 Using sort_intersect(Name,Population,Country); Using where EXPLAIN SELECT * FROM City -WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; +WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Population,Country 4,4,3 NULL 1 Using sort_intersect(PRIMARY,Population,Country); Using where EXPLAIN SELECT * FROM City -WHERE ID < 1000 AND Population > 700000 AND Country LIKE 'C%'; +WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 +AND Country BETWEEN 'S' AND 'Z'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Country,Population 4,3,4 NULL 17 Using sort_intersect(PRIMARY,Country,Population); Using where +1 SIMPLE City range PRIMARY,Population,Country PRIMARY,Country,Population 4,3,4 NULL 30 Using sort_intersect(PRIMARY,Country,Population); Using where SELECT * FROM City WHERE Name LIKE 'C%' AND Population > 1000000; ID Name Country Population @@ -682,60 +770,22 @@ ID Name Country Population 3539 Caracas VEN 1975294 3795 Chicago USA 2896016 SELECT * FROM City WHERE -Name LIKE 'M%' AND Population > 500000; +Name LIKE 'M%' AND Population > 1500000; ID Name Country Population -77 Mar del Plata ARG 512880 131 Melbourne AUS 2865329 -215 Manaus BRA 1255049 -223 Maceió BRA 786288 653 Madrid ESP 2879052 -658 Málaga ESP 530553 766 Manila PHL 1581082 942 Medan IDN 1843919 -947 Malang IDN 716862 1024 Mumbai (Bombay) IND 10500000 -1042 Madurai IND 977856 -1051 Meerut IND 753778 -1366 Mosul IRQ 879000 1381 Mashhad IRN 1887405 -1465 Milano ITA 1300977 -1810 Montréal CAN 1016376 -1816 Mississauga CAN 608072 -1945 Mudanjiang CHN 570000 2259 Medellín COL 1861265 -2300 Mbuji-Mayi COD 806475 -2440 Monrovia LBR 850000 -2487 Marrakech MAR 621914 -2523 Monterrey MEX 1108499 -2526 Mexicali MEX 764902 -2530 Mérida MEX 703324 -2537 Morelia MEX 619958 -2698 Maputo MOZ 1018938 -2711 Mandalay MMR 885300 -2734 Managua NIC 959000 -2826 Multan PAK 1182441 -2975 Marseille FRA 798430 -3070 Munich [München] DEU 1194560 -3175 Mekka SAU 965700 -3176 Medina SAU 608300 -3214 Mogadishu SOM 997000 -3364 Mersin (Içel) TUR 587212 -3434 Mykolajiv UKR 508000 -3492 Montevideo URY 1236000 3520 Minsk BLR 1674000 -3540 Maracaíbo VEN 1304776 3580 Moscow RUS 8389200 -3810 Memphis USA 650100 -3811 Milwaukee USA 596974 -SELECT * FROM City -WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; -ID Name Country Population -1810 Montréal CAN 1016376 -2259 Medellín COL 1861265 SELECT * FROM City -WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; +WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'B%'; ID Name Country Population -2516 Guadalajara MEX 1647720 +217 Guarulhos BRA 1095874 +218 Goiânia BRA 1056330 SELECT * FROM City WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; ID Name Country Population @@ -748,36 +798,112 @@ ID Name Country Population 1937 Huainan CHN 700000 1950 Hegang CHN 520000 SELECT * FROM City -WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; +WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; ID Name Country Population +1 Kabul AFG 1780000 +56 Luanda AGO 2022000 +69 Buenos Aires ARG 2982146 +70 La Matanza ARG 1266461 +71 Córdoba ARG 1157507 +126 Yerevan ARM 1248700 +130 Sydney AUS 3276207 +131 Melbourne AUS 2865329 +132 Brisbane AUS 1291117 +133 Perth AUS 1096829 +144 Baku AZE 1787800 SELECT * FROM City -WHERE ID < 1000 AND Population > 700000 AND Country LIKE 'C%'; +WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 +AND Country BETWEEN 'S' AND 'Z'; ID Name Country Population -554 Santiago de Chile CHL 4703954 +3048 Stockholm SWE 750348 +3173 Riyadh SAU 3324000 +3174 Jedda SAU 2046300 +3175 Mekka SAU 965700 +3176 Medina SAU 608300 +3197 Pikine SEN 855287 +3198 Dakar SEN 785071 +3207 Freetown SLE 850000 +3208 Singapore SGP 4017733 +3214 Mogadishu SOM 997000 +3224 Omdurman SDN 1271403 +3225 Khartum SDN 947483 +3226 Sharq al-Nil SDN 700887 +3250 Damascus SYR 1347000 +3251 Aleppo SYR 1261983 +3263 Taipei TWN 2641312 +3264 Kaohsiung TWN 1475505 +3265 Taichung TWN 940589 +3266 Tainan TWN 728060 +3305 Dar es Salaam TZA 1747000 +3320 Bangkok THA 6320174 +3349 Tunis TUN 690600 +3357 Istanbul TUR 8787958 +3358 Ankara TUR 3038159 +3359 Izmir TUR 2130359 +3360 Adana TUR 1131198 +3361 Bursa TUR 1095842 +3362 Gaziantep TUR 789056 +3363 Konya TUR 628364 +3425 Kampala UGA 890800 +3426 Kyiv UKR 2624000 +3427 Harkova [Harkiv] UKR 1500000 +3428 Dnipropetrovsk UKR 1103000 +3429 Donetsk UKR 1050000 +3430 Odesa UKR 1011000 +3431 Zaporizzja UKR 848000 +3432 Lviv UKR 788000 +3433 Kryvyi Rig UKR 703000 +3492 Montevideo URY 1236000 +3503 Toskent UZB 2117500 +3539 Caracas VEN 1975294 +3540 Maracaíbo VEN 1304776 +3541 Barquisimeto VEN 877239 +3542 Valencia VEN 794246 +3543 Ciudad Guayana VEN 663713 +3769 Ho Chi Minh City VNM 3980000 +3770 Hanoi VNM 1410000 +3771 Haiphong VNM 783133 +3793 New York USA 8008278 +3794 Los Angeles USA 3694820 +3795 Chicago USA 2896016 +3796 Houston USA 1953631 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3799 San Diego USA 1223400 +3800 Dallas USA 1188580 +3801 San Antonio USA 1144646 +3802 Detroit USA 951270 +3803 San Jose USA 894943 +3804 Indianapolis USA 791926 +3805 San Francisco USA 776733 +3806 Jacksonville USA 735167 +3807 Columbus USA 711470 +3808 Austin USA 656562 +3809 Baltimore USA 651154 +3810 Memphis USA 650100 SET SESSION sort_buffer_size = default; DROP INDEX Country ON City; CREATE INDEX CountryID ON City(Country,ID); CREATE INDEX CountryName ON City(Country,Name); EXPLAIN SELECT * FROM City -WHERE Country LIKE 'M%' AND Population > 700000; +WHERE Country LIKE 'M%' AND Population > 1000000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,CountryID,CountryName Population,CountryID 4,3 NULL 24 Using sort_intersect(Population,CountryID); Using where +1 SIMPLE City range Population,CountryID,CountryName Population,CountryID 4,3 NULL 16 Using sort_intersect(Population,CountryID); Using where EXPLAIN SELECT * FROM City -WHERE Country='CHN' AND Population > 1000000; +WHERE Country='CHN' AND Population > 1500000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,CountryID,CountryName CountryID,Population 3,4 NULL 21 Using sort_intersect(CountryID,Population); Using where +1 SIMPLE City range Population,CountryID,CountryName Population,CountryID 4,3 NULL 11 Using sort_intersect(Population,CountryID); Using where EXPLAIN SELECT * FROM City -WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%'; +WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Population,Name,CountryID,CountryName CountryName,Population 38,4 NULL 1 Using sort_intersect(CountryName,Population); Using where SELECT * FROM City USE INDEX () -WHERE Country LIKE 'M%' AND Population > 700000; +WHERE Country LIKE 'M%' AND Population > 1000000; ID Name Country Population 2464 Kuala Lumpur MYS 1297526 -2482 Bamako MLI 809552 2485 Casablanca MAR 2940623 2515 Ciudad de México MEX 8591309 2516 Guadalajara MEX 1647720 @@ -789,17 +915,8 @@ ID Name Country Population 2522 León MEX 1133576 2523 Monterrey MEX 1108499 2524 Zapopan MEX 1002239 -2525 Naucalpan de Juárez MEX 857511 -2526 Mexicali MEX 764902 -2527 Culiacán MEX 744859 -2528 Acapulco de Juárez MEX 721011 -2529 Tlalnepantla de Baz MEX 720755 -2530 Mérida MEX 703324 -2690 Chisinau MDA 719900 -2696 Ulan Bator MNG 773700 2698 Maputo MOZ 1018938 2710 Rangoon (Yangon) MMR 3361700 -2711 Mandalay MMR 885300 SELECT * FROM City WHERE Country LIKE 'M%' AND Population > 700000; ID Name Country Population @@ -828,7 +945,7 @@ ID Name Country Population 2710 Rangoon (Yangon) MMR 3361700 2711 Mandalay MMR 885300 SELECT * FROM City USE INDEX () -WHERE Country='CHN' AND Population > 1000000; +WHERE Country='CHN' AND Population > 1500000; ID Name Country Population 1890 Shanghai CHN 9696300 1891 Peking CHN 7472000 @@ -854,19 +971,8 @@ ID Name Country Population 1911 Nanchang CHN 1691600 1912 Fuzhou CHN 1593800 1913 Lanzhou CHN 1565800 -1914 Guiyang CHN 1465200 -1915 Ningbo CHN 1371200 -1916 Hefei CHN 1369100 -1917 Urumt?i [Ürümqi] CHN 1310100 -1918 Anshan CHN 1200000 -1919 Fushun CHN 1200000 -1920 Nanning CHN 1161800 -1921 Zibo CHN 1140000 -1922 Qiqihar CHN 1070000 -1923 Jilin CHN 1040000 -1924 Tangshan CHN 1040000 SELECT * FROM City -WHERE Country='CHN' AND Population > 1000000; +WHERE Country='CHN' AND Population > 1500000; ID Name Country Population 1890 Shanghai CHN 9696300 1891 Peking CHN 7472000 @@ -892,26 +998,15 @@ ID Name Country Population 1911 Nanchang CHN 1691600 1912 Fuzhou CHN 1593800 1913 Lanzhou CHN 1565800 -1914 Guiyang CHN 1465200 -1915 Ningbo CHN 1371200 -1916 Hefei CHN 1369100 -1917 Urumt?i [Ürümqi] CHN 1310100 -1918 Anshan CHN 1200000 -1919 Fushun CHN 1200000 -1920 Nanning CHN 1161800 -1921 Zibo CHN 1140000 -1922 Qiqihar CHN 1070000 -1923 Jilin CHN 1040000 -1924 Tangshan CHN 1040000 SELECT * FROM City USE INDEX () -WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%'; +WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; ID Name Country Population 1892 Chongqing CHN 6351600 1898 Chengdu CHN 3361500 1900 Changchun CHN 2812000 1910 Changsha CHN 1809800 SELECT * FROM City -WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%'; +WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; ID Name Country Population 1892 Chongqing CHN 6351600 1898 Chengdu CHN 3361500 diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index fa19dee7d26..abb9642e6e8 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -679,8 +679,6 @@ INSERT INTO t1(b,c) SELECT b,c FROM t2; UPDATE t2 SET c='2007-01-03'; INSERT INTO t1(b,c) SELECT b,c FROM t2; set @@sort_buffer_size=8192; -Warnings: -Warning 1292 Truncated incorrect sort_buffer_size value: '8192' SELECT COUNT(*) FROM t1; COUNT(*) 3072 diff --git a/mysql-test/suite/pbxt/r/subselect.result b/mysql-test/suite/pbxt/r/subselect.result index 69f8e2534f7..d55fed8e90d 100644 --- a/mysql-test/suite/pbxt/r/subselect.result +++ b/mysql-test/suite/pbxt/r/subselect.result @@ -3667,8 +3667,6 @@ CREATE TABLE t1 (a int, b int auto_increment, PRIMARY KEY (b)); CREATE TABLE t2 (x int auto_increment, y int, z int, PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b)); SET SESSION sort_buffer_size = 32 * 1024; -Warnings: -Warning 1292 Truncated incorrect sort_buffer_size value: '32768' SELECT SQL_NO_CACHE COUNT(*) FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c FROM t1) t; @@ -4104,8 +4102,6 @@ INSERT INTO `t1` VALUES ('asdf','2007-02-08 01:11:26'); INSERT INTO `t2` VALUES ('abcdefghijk'); INSERT INTO `t2` VALUES ('asdf'); SET session sort_buffer_size=8192; -Warnings: -Warning 1292 Truncated incorrect sort_buffer_size value: '8192' SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2; d1 1 diff --git a/mysql-test/t/index_intersect.test b/mysql-test/t/index_intersect.test index 0fe89b714fa..ef70134b614 100644 --- a/mysql-test/t/index_intersect.test +++ b/mysql-test/t/index_intersect.test @@ -44,7 +44,7 @@ SELECT COUNT(*) FROM City; SELECT COUNT(*) FROM City WHERE Name LIKE 'C%'; SELECT COUNT(*) FROM City WHERE Name LIKE 'M%'; SELECT COUNT(*) FROM City WHERE Population > 1000000; -SELECT COUNT(*) FROM City WHERE Population > 500000; +SELECT COUNT(*) FROM City WHERE Population > 1500000; SELECT COUNT(*) FROM City WHERE Population > 300000; SELECT COUNT(*) FROM City WHERE Population > 5000000; @@ -60,7 +60,7 @@ SELECT * FROM City WHERE EXPLAIN SELECT * FROM City WHERE - Name LIKE 'M%' AND Population > 500000; + Name LIKE 'M%' AND Population > 1500000; EXPLAIN SELECT * FROM City @@ -84,10 +84,10 @@ SELECT * FROM City SELECT * FROM City USE INDEX () - WHERE Name LIKE 'M%' AND Population > 500000; + WHERE Name LIKE 'M%' AND Population > 1500000; SELECT * FROM City - WHERE Name LIKE 'M%' AND Population > 500000; + WHERE Name LIKE 'M%' AND Population > 1500000; SELECT * FROM City USE INDEX () @@ -104,16 +104,15 @@ SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 5000000; -# The output of the next 7 queries tells us about selectivities +# The output of the next 6 queries tells us about selectivities # of the conditions utilized in 3 queries following after them SELECT COUNT(*) FROM City WHERE Name BETWEEN 'M' AND 'N'; SELECT COUNT(*) FROM City WHERE Name BETWEEN 'G' AND 'J'; SELECT COUNT(*) FROM City WHERE Population > 1000000; -SELECT COUNT(*) FROM City WHERE Population > 700000; SELECT COUNT(*) FROM City WHERE Population > 500000; SELECT COUNT(*) FROM City WHERE Country LIKE 'C%'; -SELECT COUNT(*) FROM City WHERE Country LIKE 'L%'; +SELECT COUNT(*) FROM City WHERE Country LIKE 'B%'; # The pattern of the WHERE condition used in the following 3 queries is @@ -129,7 +128,7 @@ SELECT * FROM City EXPLAIN SELECT * FROM City - WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'L%'; + WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; EXPLAIN SELECT * FROM City @@ -149,10 +148,10 @@ SELECT * FROM City SELECT * FROM City USE INDEX () - WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; + WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; SELECT * FROM City - WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; + WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; SELECT * FROM City USE INDEX () @@ -162,17 +161,20 @@ SELECT * FROM City WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; -# The output of the next 9 queries tells us about selectivities +# The output of the next 12 queries tells us about selectivities # of the conditions utilized in 5 queries following after them -SELECT COUNT(*) FROM City WHERE ID BETWEEN 500 AND 999; -SELECT COUNT(*) FROM City WHERE ID BETWEEN 3500 AND 3999; -SELECT COUNT(*) FROM City WHERE ID BETWEEN 1 AND 1000; +SELECT COUNT(*) FROM City WHERE ID BETWEEN 501 AND 1000; +SELECT COUNT(*) FROM City WHERE ID BETWEEN 1 AND 500; +SELECT COUNT(*) FROM City WHERE ID BETWEEN 2001 AND 2500; +SELECT COUNT(*) FROM City WHERE ID BETWEEN 3701 AND 4000; SELECT COUNT(*) FROM City WHERE Population > 700000; SELECT COUNT(*) FROM City WHERE Population > 1000000; SELECT COUNT(*) FROM City WHERE Population > 300000; +SELECT COUNT(*) FROM City WHERE Population > 600000; SELECT COUNT(*) FROM City WHERE Country LIKE 'C%'; SELECT COUNT(*) FROM City WHERE Country LIKE 'A%'; +SELECT COUNT(*) FROM City WHERE Country LIKE 'L%'; SELECT COUNT(*) FROM City WHERE Country BETWEEN 'S' AND 'Z'; @@ -181,7 +183,7 @@ SELECT COUNT(*) FROM City WHERE Country BETWEEN 'S' AND 'Z'; # with key1 happens to be a primary key (it matters only for InnoDB) # Varying values of the constants in the conjuncts of the condition # we can get index intersection either over all three keys, or over -# different pairs, or a range sacn over one of these keys. +# different pairs, or a range scan over one of these keys. # Bear in mind that the condition (Country LIKE 'A%') is actually # equivalent to the condition (Country BETWEEN 'A' AND 'B') for the # tested instance the table City. @@ -189,24 +191,24 @@ SELECT COUNT(*) FROM City WHERE Country BETWEEN 'S' AND 'Z'; EXPLAIN SELECT * FROM City - WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%'; + WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; EXPLAIN SELECT * FROM City - WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; + WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; EXPLAIN SELECT * FROM City - WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%'; + WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'L%'; EXPLAIN SELECT * FROM City - WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000 + WHERE ID BETWEEN 3701 AND 4000 AND Population > 1000000 AND Country BETWEEN 'S' AND 'Z'; EXPLAIN SELECT * FROM City - WHERE ID BETWEEN 1 AND 1000 AND Population > 700000 + WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 AND Country BETWEEN 'S' AND 'Z' ; @@ -216,41 +218,41 @@ SELECT * FROM City SELECT * FROM City USE INDEX () - WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%'; + WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; SELECT * FROM City - WHERE ID BETWEEN 500 AND 999 AND Population > 700000 AND Country LIKE 'C%'; + WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; SELECT * FROM City USE INDEX () - WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; + WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; SELECT * FROM City - WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; + WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; SELECT * FROM City USE INDEX () - WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%'; + WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'L%'; SELECT * FROM City - WHERE ID BETWEEN 500 AND 999 AND Population > 300000 AND Country LIKE 'C%'; + WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'L%'; SELECT * FROM City USE INDEX () - WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000 + WHERE ID BETWEEN 3701 AND 4000 AND Population > 700000 AND Country BETWEEN 'S' AND 'Z'; SELECT * FROM City - WHERE ID BETWEEN 3500 AND 3999 AND Population > 700000 + WHERE ID BETWEEN 3701 AND 4000 AND Population > 700000 AND Country BETWEEN 'S' AND 'Z'; SELECT * FROM City USE INDEX () - WHERE ID BETWEEN 1 AND 1000 AND Population > 700000 + WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 AND Country BETWEEN 'S' AND 'Z' ; SELECT * FROM City - WHERE ID BETWEEN 1 AND 1000 AND Population > 700000 + WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 AND Country BETWEEN 'S' AND 'Z' ; @@ -267,16 +269,12 @@ SELECT * FROM City WHERE EXPLAIN SELECT * FROM City WHERE - Name LIKE 'M%' AND Population > 500000; + Name LIKE 'M%' AND Population > 1500000; -EXPLAIN -SELECT * FROM City - WHERE Name LIKE 'C%' AND Population > 1000000 AND Country LIKE 'C%'; - EXPLAIN SELECT * FROM City - WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; + WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%'; EXPLAIN SELECT * FROM City @@ -285,11 +283,12 @@ SELECT * FROM City EXPLAIN SELECT * FROM City - WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; + WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; EXPLAIN SELECT * FROM City - WHERE ID < 1000 AND Population > 700000 AND Country LIKE 'C%'; + WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 + AND Country BETWEEN 'S' AND 'Z'; #Yet the query themselves return the correct results in this case as well @@ -299,24 +298,22 @@ SELECT * FROM City WHERE Name LIKE 'C%' AND Population > 1000000; SELECT * FROM City WHERE - Name LIKE 'M%' AND Population > 500000; + Name LIKE 'M%' AND Population > 1500000; -SELECT * FROM City - WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%'; - SELECT * FROM City - WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'M%'; + WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'B%'; SELECT * FROM City WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%'; SELECT * FROM City - WHERE ID BETWEEN 500 AND 999 AND Population > 1000000 AND Country LIKE 'A%'; + WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; SELECT * FROM City - WHERE ID < 1000 AND Population > 700000 AND Country LIKE 'C%'; + WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 + AND Country BETWEEN 'S' AND 'Z'; SET SESSION sort_buffer_size = default; @@ -343,39 +340,39 @@ ANALYZE TABLE City; EXPLAIN SELECT * FROM City - WHERE Country LIKE 'M%' AND Population > 700000; + WHERE Country LIKE 'M%' AND Population > 1000000; EXPLAIN SELECT * FROM City - WHERE Country='CHN' AND Population > 1000000; + WHERE Country='CHN' AND Population > 1500000; EXPLAIN SELECT * FROM City - WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%'; + WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; # Check that the previous 3 plans return the right results when executed SELECT * FROM City USE INDEX () - WHERE Country LIKE 'M%' AND Population > 700000; + WHERE Country LIKE 'M%' AND Population > 1000000; SELECT * FROM City WHERE Country LIKE 'M%' AND Population > 700000; SELECT * FROM City USE INDEX () - WHERE Country='CHN' AND Population > 1000000; + WHERE Country='CHN' AND Population > 1500000; SELECT * FROM City - WHERE Country='CHN' AND Population > 1000000; + WHERE Country='CHN' AND Population > 1500000; SELECT * FROM City USE INDEX () - WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%'; + WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; SELECT * FROM City - WHERE Country='CHN' AND Population > 1000000 AND Name LIKE 'C%'; + WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%'; DROP DATABASE world; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index f088cf87bca..9c961a45164 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -5112,7 +5112,7 @@ double get_unique_intersect_cost(COMMON_INDEX_INTERSECTION_INFO *common, common->max_memory_size, common->compare_factor, TRUE, in_memory); - if (in_memory) + if (*in_memory) *in_memory_cost= cost; } return cost; @@ -5124,7 +5124,7 @@ double get_cpk_filter_cost(INDEX_SCAN_INFO *index_scan, INDEX_SCAN_INFO *cpk_scan, double compare_factor) { - return log((double) cpk_scan->range_count) / (compare_factor * M_LN2) * + return log((double) (cpk_scan->range_count+1)) / (compare_factor * M_LN2) * index_scan->records; } @@ -5174,7 +5174,8 @@ bool check_index_intersect_extension(PARTIAL_INDEX_INTERSECTION_INFO *curr, return FALSE; records_in_scans= curr->records_in_scans + index_scan_records; - next->in_memory= curr->in_memory; + if ((next->in_memory= curr->in_memory)) + next->in_memory_cost= curr->in_memory_cost; records= records_in_index_intersect_extension(curr, ext_index_scan); if (idx && records > curr->records) @@ -5207,7 +5208,7 @@ bool check_index_intersect_extension(PARTIAL_INDEX_INTERSECTION_INFO *curr, { double cost2; bool in_memory_save= next->in_memory; - if (!idx) + if (idx) { next->length= curr->length+1; records2= records_in_index_intersect_extension(next, cpk_scan); diff --git a/sql/sql_class.h b/sql/sql_class.h index bde632a87e2..274c4f558f4 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2983,7 +2983,8 @@ public: { DBUG_ENTER("unique_add"); DBUG_PRINT("info", ("tree %u - %lu", tree.elements_in_tree, max_elements)); - if (tree.elements_in_tree > max_elements && flush()) + if (!(tree.flag & TREE_ONLY_DUPS) && + tree.elements_in_tree >= max_elements && flush()) DBUG_RETURN(1); DBUG_RETURN(!tree_insert(&tree, ptr, 0, tree.custom_arg)); } From 25704af0b28e1476428092cf21073cd96663cc71 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 4 Dec 2010 10:40:07 -0800 Subject: [PATCH 12/33] Adjusted results in suite/innodb_plugin/r/innodb_mysql.result. Made range_vs_index_merge.test platform independent --- mysql-test/suite/innodb_plugin/r/innodb_mysql.result | 2 -- mysql-test/t/range_vs_index_merge.test | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result index 53e979c350f..50ef063e1b4 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result +++ b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result @@ -679,8 +679,6 @@ INSERT INTO t1(b,c) SELECT b,c FROM t2; UPDATE t2 SET c='2007-01-03'; INSERT INTO t1(b,c) SELECT b,c FROM t2; set @@sort_buffer_size=8192; -Warnings: -Warning 1292 Truncated incorrect sort_buffer_size value: '8192' SELECT COUNT(*) FROM t1; COUNT(*) 3072 diff --git a/mysql-test/t/range_vs_index_merge.test b/mysql-test/t/range_vs_index_merge.test index 7ddd2cb5cea..d63a88ebf74 100755 --- a/mysql-test/t/range_vs_index_merge.test +++ b/mysql-test/t/range_vs_index_merge.test @@ -202,6 +202,7 @@ EXPLAIN SELECT * FROM City WHERE (ID < 30) OR (ID BETWEEN 100 AND 150); EXPLAIN SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 300 AND 600); +--replace_result 2921 2950 EXPLAIN SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1800); EXPLAIN From bfb7727526b2081074325142b7a84426c89531fa Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 4 Dec 2010 19:19:55 -0800 Subject: [PATCH 13/33] Fixed LP bug #684117. A crash may happenin the cases when the range optimizer tried to OR two index merge such that the second one contained less range trees than the first one. The bug was introduced by the patch of MWL#24: "index_merge: fair choice between index_merge union and range access". --- mysql-test/r/range_vs_index_merge.result | 12 ++++++++++++ mysql-test/r/range_vs_index_merge_innodb.result | 12 ++++++++++++ mysql-test/t/range_vs_index_merge.test | 16 ++++++++++++++++ sql/opt_range.cc | 3 ++- 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/range_vs_index_merge.result b/mysql-test/r/range_vs_index_merge.result index b616afc9578..1f5d2564be2 100644 --- a/mysql-test/r/range_vs_index_merge.result +++ b/mysql-test/r/range_vs_index_merge.result @@ -1314,4 +1314,16 @@ WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge PRIMARY,idx1,idx2,idx3 idx3,idx2,PRIMARY,idx1 67,13,4,3 NULL 8 Using sort_union(idx3,idx2,PRIMARY,idx1); Using where DROP TABLE t1; +CREATE TABLE t1 ( +f1 int, f2 int, f3 int, f4 int, f5 int, +PRIMARY KEY (f4), KEY (f1), KEY (f2), KEY (f3) +) ; +INSERT INTO t1 VALUES (0,0,NULL,9,5), (0,0,1,9425,NULL); +SELECT f5 FROM t1 +WHERE f2 != 1 OR f1 IS NULL OR f4 = 4 OR +f2 AND (f4 BETWEEN 6 AND 255 OR f3 IS NULL); +f5 +5 +NULL +DROP TABLE t1; set session optimizer_switch='index_merge_sort_intersection=default'; diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result index 037e23eae5d..8a373115522 100644 --- a/mysql-test/r/range_vs_index_merge_innodb.result +++ b/mysql-test/r/range_vs_index_merge_innodb.result @@ -1315,5 +1315,17 @@ WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge PRIMARY,idx1,idx2,idx3 idx3,idx2,idx1,PRIMARY 67,13,3,4 NULL 9 Using sort_union(idx3,idx2,idx1,PRIMARY); Using where DROP TABLE t1; +CREATE TABLE t1 ( +f1 int, f2 int, f3 int, f4 int, f5 int, +PRIMARY KEY (f4), KEY (f1), KEY (f2), KEY (f3) +) ; +INSERT INTO t1 VALUES (0,0,NULL,9,5), (0,0,1,9425,NULL); +SELECT f5 FROM t1 +WHERE f2 != 1 OR f1 IS NULL OR f4 = 4 OR +f2 AND (f4 BETWEEN 6 AND 255 OR f3 IS NULL); +f5 +5 +NULL +DROP TABLE t1; set session optimizer_switch='index_merge_sort_intersection=default'; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/t/range_vs_index_merge.test b/mysql-test/t/range_vs_index_merge.test index d63a88ebf74..036d8837d0b 100755 --- a/mysql-test/t/range_vs_index_merge.test +++ b/mysql-test/t/range_vs_index_merge.test @@ -925,6 +925,22 @@ SELECT COUNT(*) FROM t1 DROP TABLE t1; +# +# Bug #637978: ORing of two index merge that caused a crash +# + +CREATE TABLE t1 ( + f1 int, f2 int, f3 int, f4 int, f5 int, + PRIMARY KEY (f4), KEY (f1), KEY (f2), KEY (f3) +) ; +INSERT INTO t1 VALUES (0,0,NULL,9,5), (0,0,1,9425,NULL); + +SELECT f5 FROM t1 + WHERE f2 != 1 OR f1 IS NULL OR f4 = 4 OR + f2 AND (f4 BETWEEN 6 AND 255 OR f3 IS NULL); + +DROP TABLE t1; + #the following command must be the last one in the file set session optimizer_switch='index_merge_sort_intersection=default'; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 9c961a45164..7c293648d23 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1195,7 +1195,8 @@ int SEL_IMERGE::or_sel_imerge_with_checks(RANGE_OPT_PARAM *param, { *is_last_check_pass= TRUE; SEL_TREE** tree= imerge->trees; - for (uint i= 0; i < n_trees; i++, tree++) + SEL_TREE** tree_end= imerge->trees_next; + for ( ; tree < tree_end; tree++) { uint rc; bool is_last= TRUE; From 1684c3e9a0fbe3d439e95924a49620ec315d03ed Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sun, 5 Dec 2010 13:49:04 -0800 Subject: [PATCH 14/33] Fixed LP bug#684086. If a primary key was used in the index intersection for an InnoDB database the size of the memory allocated for the best index intersection plan was one element less than it was needed. That could cause a memory overwrite and a crash as a result of it. --- mysql-test/r/index_intersect.result | 36 +++++++++++++++++++++ mysql-test/r/index_intersect_innodb.result | 33 +++++++++++++++++++ mysql-test/t/index_intersect.test | 37 ++++++++++++++++++++++ sql/opt_range.cc | 5 +-- 4 files changed, 109 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/index_intersect.result b/mysql-test/r/index_intersect.result index 1bae4a07168..fdb4885e071 100644 --- a/mysql-test/r/index_intersect.result +++ b/mysql-test/r/index_intersect.result @@ -1013,4 +1013,40 @@ ID Name Country Population 1910 Changsha CHN 1809800 DROP DATABASE world; use test; +CREATE TABLE t1 ( +f1 int, +f4 varchar(32), +f5 int, +PRIMARY KEY (f1), +KEY (f4) +) ENGINE=InnoDB; +Warnings: +Warning 1286 Unknown table engine 'InnoDB' +Warning 1266 Using storage engine MyISAM for table 't1' +INSERT INTO t1 VALUES +(5,'H',1), (9,'g',0), (527,'i',0), (528,'y',1), (529,'S',6), +(530,'m',7), (531,'b',2), (532,'N',1), (533,'V',NULL), (534,'l',1), +(535,'M',0), (536,'w',1), (537,'j',5), (538,'l',0), (539,'n',2), +(540,'m',2), (541,'r',2), (542,'l',2), (543,'h',3),(544,'o',0), +(956,'h',0), (957,'g',0), (958,'W',5), (959,'s',3), (960,'w',0), +(961,'q',0), (962,'e',NULL), (963,'u',7), (964,'q',1), (965,'N',NULL), +(966,'e',0), (967,'t',3), (968,'e',6), (969,'f',NULL), (970,'j',0), +(971,'s',3), (972,'I',0), (973,'h',4), (974,'g',1), (975,'s',0), +(976,'r',3), (977,'x',1), (978,'v',8), (979,'j',NULL), (980,'z',7), +(981,'t',9), (982,'j',5), (983,'u',NULL), (984,'g',6), (985,'w',1), +(986,'h',1), (987,'v',0), (988,'v',0), (989,'c',2), (990,'b',7), +(991,'z',0), (992,'M',1), (993,'u',2), (994,'r',2), (995,'b',4), +(996,'A',2), (997,'u',0), (998,'a',0), (999,'j',2), (1,'I',2); +EXPLAIN +SELECT * FROM t1 +WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY,f4 f4 35 NULL 5 Using where +SELECT * FROM t1 +WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ; +f1 f4 f5 +996 A 2 +998 a 0 +994 r 2 +DROP TABLE t1; SET SESSION optimizer_switch='index_merge_sort_intersection=on'; diff --git a/mysql-test/r/index_intersect_innodb.result b/mysql-test/r/index_intersect_innodb.result index fc85846110a..7b53761935a 100644 --- a/mysql-test/r/index_intersect_innodb.result +++ b/mysql-test/r/index_intersect_innodb.result @@ -1014,5 +1014,38 @@ ID Name Country Population 1910 Changsha CHN 1809800 DROP DATABASE world; use test; +CREATE TABLE t1 ( +f1 int, +f4 varchar(32), +f5 int, +PRIMARY KEY (f1), +KEY (f4) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES +(5,'H',1), (9,'g',0), (527,'i',0), (528,'y',1), (529,'S',6), +(530,'m',7), (531,'b',2), (532,'N',1), (533,'V',NULL), (534,'l',1), +(535,'M',0), (536,'w',1), (537,'j',5), (538,'l',0), (539,'n',2), +(540,'m',2), (541,'r',2), (542,'l',2), (543,'h',3),(544,'o',0), +(956,'h',0), (957,'g',0), (958,'W',5), (959,'s',3), (960,'w',0), +(961,'q',0), (962,'e',NULL), (963,'u',7), (964,'q',1), (965,'N',NULL), +(966,'e',0), (967,'t',3), (968,'e',6), (969,'f',NULL), (970,'j',0), +(971,'s',3), (972,'I',0), (973,'h',4), (974,'g',1), (975,'s',0), +(976,'r',3), (977,'x',1), (978,'v',8), (979,'j',NULL), (980,'z',7), +(981,'t',9), (982,'j',5), (983,'u',NULL), (984,'g',6), (985,'w',1), +(986,'h',1), (987,'v',0), (988,'v',0), (989,'c',2), (990,'b',7), +(991,'z',0), (992,'M',1), (993,'u',2), (994,'r',2), (995,'b',4), +(996,'A',2), (997,'u',0), (998,'a',0), (999,'j',2), (1,'I',2); +EXPLAIN +SELECT * FROM t1 +WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range PRIMARY,f4 PRIMARY,f4 4,35 NULL 1 Using sort_intersect(PRIMARY,f4); Using where +SELECT * FROM t1 +WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ; +f1 f4 f5 +994 r 2 +996 A 2 +998 a 0 +DROP TABLE t1; SET SESSION optimizer_switch='index_merge_sort_intersection=on'; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/t/index_intersect.test b/mysql-test/t/index_intersect.test index ef70134b614..d8fad05a4b0 100644 --- a/mysql-test/t/index_intersect.test +++ b/mysql-test/t/index_intersect.test @@ -379,4 +379,41 @@ DROP DATABASE world; use test; +# +# Bug #684086: crash with EXPLAIN in InnoDB for index intersection +# of two indexes one of which is primary +# + +CREATE TABLE t1 ( + f1 int, + f4 varchar(32), + f5 int, + PRIMARY KEY (f1), + KEY (f4) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES + (5,'H',1), (9,'g',0), (527,'i',0), (528,'y',1), (529,'S',6), + (530,'m',7), (531,'b',2), (532,'N',1), (533,'V',NULL), (534,'l',1), + (535,'M',0), (536,'w',1), (537,'j',5), (538,'l',0), (539,'n',2), + (540,'m',2), (541,'r',2), (542,'l',2), (543,'h',3),(544,'o',0), + (956,'h',0), (957,'g',0), (958,'W',5), (959,'s',3), (960,'w',0), + (961,'q',0), (962,'e',NULL), (963,'u',7), (964,'q',1), (965,'N',NULL), + (966,'e',0), (967,'t',3), (968,'e',6), (969,'f',NULL), (970,'j',0), + (971,'s',3), (972,'I',0), (973,'h',4), (974,'g',1), (975,'s',0), + (976,'r',3), (977,'x',1), (978,'v',8), (979,'j',NULL), (980,'z',7), + (981,'t',9), (982,'j',5), (983,'u',NULL), (984,'g',6), (985,'w',1), + (986,'h',1), (987,'v',0), (988,'v',0), (989,'c',2), (990,'b',7), + (991,'z',0), (992,'M',1), (993,'u',2), (994,'r',2), (995,'b',4), + (996,'A',2), (997,'u',0), (998,'a',0), (999,'j',2), (1,'I',2); + +EXPLAIN +SELECT * FROM t1 +WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ; + +SELECT * FROM t1 +WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ; + +DROP TABLE t1; + SET SESSION optimizer_switch='index_merge_sort_intersection=on'; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 7c293648d23..60b62b05b60 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -4992,10 +4992,11 @@ bool prepare_search_best_index_intersect(PARAM *param, common->best_uses_cpk= FALSE; common->best_cost= cutoff_cost + 0.01; common->best_length= 0; - + if (!(common->best_intersect= (INDEX_SCAN_INFO **) alloc_root (param->mem_root, - sizeof(INDEX_SCAN_INFO *) * i))) + sizeof(INDEX_SCAN_INFO *) * + (i + test(cpk_scan != NULL))))) return TRUE; uint calc_cost_buff_size= From 67180d655a9b47e72f4b96a5f5941c1733b32e23 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sun, 5 Dec 2010 19:09:37 -0800 Subject: [PATCH 15/33] Fixed LP bug #684117. A crash may happenin the cases when the range optimizer tried to OR two index merge such that the second one contained less range trees than the first one. The bug was introduced by the patch of MWL#24: "index_merge: fair choice between index_merge union and range access". --- mysql-test/r/range_vs_index_merge.result | 12 ++++++++++++ mysql-test/r/range_vs_index_merge_innodb.result | 12 ++++++++++++ mysql-test/t/range_vs_index_merge.test | 17 +++++++++++++++++ sql/opt_range.cc | 3 ++- 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/range_vs_index_merge.result b/mysql-test/r/range_vs_index_merge.result index 0f9c46f182d..660a7d4ff38 100644 --- a/mysql-test/r/range_vs_index_merge.result +++ b/mysql-test/r/range_vs_index_merge.result @@ -1386,3 +1386,15 @@ WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge PRIMARY,idx1,idx2,idx3 idx3,idx2,PRIMARY,idx1 67,13,4,3 NULL 8 Using sort_union(idx3,idx2,PRIMARY,idx1); Using where DROP TABLE t1; +CREATE TABLE t1 ( +f1 int, f2 int, f3 int, f4 int, f5 int, +PRIMARY KEY (f4), KEY (f1), KEY (f2), KEY (f3) +) ; +INSERT INTO t1 VALUES (0,0,NULL,9,5), (0,0,1,9425,NULL); +SELECT f5 FROM t1 +WHERE f2 != 1 OR f1 IS NULL OR f4 = 4 OR +f2 AND (f4 BETWEEN 6 AND 255 OR f3 IS NULL); +f5 +5 +NULL +DROP TABLE t1; diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result index 2251119996a..647be9b02c9 100644 --- a/mysql-test/r/range_vs_index_merge_innodb.result +++ b/mysql-test/r/range_vs_index_merge_innodb.result @@ -1387,4 +1387,16 @@ WHERE c = 'i' OR b IN ( 'Arkansas' , 'd' , 'pdib' , 'can' ) OR id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index_merge PRIMARY,idx1,idx2,idx3 idx3,idx2,idx1,PRIMARY 67,13,3,4 NULL 9 Using sort_union(idx3,idx2,idx1,PRIMARY); Using where DROP TABLE t1; +CREATE TABLE t1 ( +f1 int, f2 int, f3 int, f4 int, f5 int, +PRIMARY KEY (f4), KEY (f1), KEY (f2), KEY (f3) +) ; +INSERT INTO t1 VALUES (0,0,NULL,9,5), (0,0,1,9425,NULL); +SELECT f5 FROM t1 +WHERE f2 != 1 OR f1 IS NULL OR f4 = 4 OR +f2 AND (f4 BETWEEN 6 AND 255 OR f3 IS NULL); +f5 +5 +NULL +DROP TABLE t1; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/t/range_vs_index_merge.test b/mysql-test/t/range_vs_index_merge.test index f57fced6da6..256c5c83ba4 100755 --- a/mysql-test/t/range_vs_index_merge.test +++ b/mysql-test/t/range_vs_index_merge.test @@ -918,3 +918,20 @@ SELECT COUNT(*) FROM t1 (pk BETWEEN 120 AND 79 + 255 OR a IN ( 4 , 179 , 1 ) ) AND a > 8 ; DROP TABLE t1; + +# +# Bug #684117: ORing of two index merge that caused a crash +# + +CREATE TABLE t1 ( + f1 int, f2 int, f3 int, f4 int, f5 int, + PRIMARY KEY (f4), KEY (f1), KEY (f2), KEY (f3) +) ; +INSERT INTO t1 VALUES (0,0,NULL,9,5), (0,0,1,9425,NULL); + +SELECT f5 FROM t1 + WHERE f2 != 1 OR f1 IS NULL OR f4 = 4 OR + f2 AND (f4 BETWEEN 6 AND 255 OR f3 IS NULL); + +DROP TABLE t1; + diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 1342c1ef331..13473cd0e89 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1187,7 +1187,8 @@ int SEL_IMERGE::or_sel_imerge_with_checks(RANGE_OPT_PARAM *param, { *is_last_check_pass= TRUE; SEL_TREE** tree= imerge->trees; - for (uint i= 0; i < n_trees; i++, tree++) + SEL_TREE** tree_end= imerge->trees_next; + for ( ; tree < tree_end; tree++) { uint rc; bool is_last= TRUE; From 1b9e0feb54a91341c1e111b0a6a30d90222e2b67 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sun, 5 Dec 2010 19:44:29 -0800 Subject: [PATCH 16/33] Made join order in two queries predetermined. --- mysql-test/include/index_merge1.inc | 4 ++-- mysql-test/r/index_merge_myisam.result | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/include/index_merge1.inc b/mysql-test/include/index_merge1.inc index d137b0957c0..b3e61802dcf 100644 --- a/mysql-test/include/index_merge1.inc +++ b/mysql-test/include/index_merge1.inc @@ -334,12 +334,12 @@ update t0 set key2=1, key3=1, key4=1, key5=1,key6=1,key7=1 where key7 < 500; --replace_column 9 # --replace_result "4,4,4,4,4,4,4" X "4,4,4,4,4,4" X "i6,i7" "i6,i7?" "i6" "i6,i7?" explain select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5) - from t0 as A, t0 as B + from t0 as A straight_join t0 as B where (A.key1 = 1 and A.key2 = 1 and A.key3 = 1 and A.key4=1 and A.key5=1 and A.key6=1 and A.key7 = 1 or A.key8=1) and (B.key1 = 1 and B.key2 = 1 and B.key3 = 1 and B.key4=1 and B.key5=1 and B.key6=1 and B.key7 = 1 or B.key8=1); select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5) - from t0 as A, t0 as B + from t0 as A straight_join t0 as B where (A.key1 = 1 and A.key2 = 1 and A.key3 = 1 and A.key4=1 and A.key5=1 and A.key6=1 and A.key7 = 1 or A.key8=1) and (B.key1 = 1 and B.key2 = 1 and B.key3 = 1 and B.key4=1 and B.key5=1 and B.key6=1 and B.key7 = 1 or B.key8=1); diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result index c98062d7da0..db0b4abb7d5 100644 --- a/mysql-test/r/index_merge_myisam.result +++ b/mysql-test/r/index_merge_myisam.result @@ -374,14 +374,14 @@ max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.ke alter table t0 add filler1 char(200), add filler2 char(200), add filler3 char(200); update t0 set key2=1, key3=1, key4=1, key5=1,key6=1,key7=1 where key7 < 500; explain select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5) -from t0 as A, t0 as B +from t0 as A straight_join t0 as B where (A.key1 = 1 and A.key2 = 1 and A.key3 = 1 and A.key4=1 and A.key5=1 and A.key6=1 and A.key7 = 1 or A.key8=1) and (B.key1 = 1 and B.key2 = 1 and B.key3 = 1 and B.key4=1 and B.key5=1 and B.key6=1 and B.key7 = 1 or B.key8=1); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE A index_merge i1,i2,i3,i4,i5,i6,i7?,i8 i2,i3,i4,i5,i6,i7?,i8 X NULL # Using union(intersect(i2,i3,i4,i5,i6,i7?),i8); Using where 1 SIMPLE B index_merge i1,i2,i3,i4,i5,i6,i7?,i8 i2,i3,i4,i5,i6,i7?,i8 X NULL # Using union(intersect(i2,i3,i4,i5,i6,i7?),i8); Using where; Using join buffer select max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5) -from t0 as A, t0 as B +from t0 as A straight_join t0 as B where (A.key1 = 1 and A.key2 = 1 and A.key3 = 1 and A.key4=1 and A.key5=1 and A.key6=1 and A.key7 = 1 or A.key8=1) and (B.key1 = 1 and B.key2 = 1 and B.key3 = 1 and B.key4=1 and B.key5=1 and B.key6=1 and B.key7 = 1 or B.key8=1); max(A.key1 + B.key1 + A.key2 + B.key2 + A.key3 + B.key3 + A.key4 + B.key4 + A.key5 + B.key5) From c44c9207f05d06f8dd59bb23b6265a645b9e1102 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 7 Dec 2010 12:14:28 -0800 Subject: [PATCH 17/33] Fixed LP bug #685952. When ORing two AND-OR formulas the range optimizer could miss a conjunct in one of AND-OR formulas in the result. If the index merge union plan to access a table is formed by this formula that, in general, is not inferred from the original where/on condition,the query could return an incorrect result set. --- mysql-test/r/range_vs_index_merge.result | 62 +++++++++++++++++ .../r/range_vs_index_merge_innodb.result | 62 +++++++++++++++++ mysql-test/t/range_vs_index_merge.test | 68 +++++++++++++++++++ sql/opt_range.cc | 5 +- 4 files changed, 196 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/range_vs_index_merge.result b/mysql-test/r/range_vs_index_merge.result index 660a7d4ff38..dccb2e3b836 100644 --- a/mysql-test/r/range_vs_index_merge.result +++ b/mysql-test/r/range_vs_index_merge.result @@ -1398,3 +1398,65 @@ f5 5 NULL DROP TABLE t1; +CREATE TABLE t1 ( +f1 int, f2 int, f3 int, f4 int, +PRIMARY KEY (f1), KEY (f3), KEY (f4) +); +INSERT INTO t1 VALUES (9,0,2,6), (9930,0,0,NULL); +SET SESSION optimizer_switch='index_merge_intersection=off'; +SET SESSION optimizer_switch='index_merge_sort_union=off'; +SET SESSION optimizer_switch='index_merge_union=off'; +EXPLAIN +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) +WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 +OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL PRIMARY,f3,f4 NULL NULL NULL 2 Using where +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) +WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 +OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); +f1 f2 f3 f4 +9 0 2 6 +SET SESSION optimizer_switch='index_merge_union=on'; +EXPLAIN +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) +WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 +OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL PRIMARY,f3,f4 NULL NULL NULL 2 Using where +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) +WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 +OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); +f1 f2 f3 f4 +9 0 2 6 +INSERT INTO t1 VALUES +(93,0,3,6), (9933,0,3,3), (94,0,4,6), (9934,0,4,4), +(95,0,5,6), (9935,0,5,5), (96,0,6,6), (9936,0,6,6), +(97,0,7,6), (9937,0,7,7), (98,0,8,6), (9938,0,8,8), +(99,0,9,6), (9939,0,9,9); +SET SESSION optimizer_switch='index_merge_union=off'; +EXPLAIN +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) +WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 +OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL PRIMARY,f3,f4 NULL NULL NULL 16 Using where +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) +WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 +OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); +f1 f2 f3 f4 +9 0 2 6 +SET SESSION optimizer_switch='index_merge_union=on'; +EXPLAIN +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) +WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 +OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge PRIMARY,f3,f4 f3,PRIMARY,f3 5,4,5 NULL 3 Using union(f3,PRIMARY,f3); Using where +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) +WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 +OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); +f1 f2 f3 f4 +9 0 2 6 +SET SESSION optimizer_switch=DEFAULT; +DROP TABLE t1; diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result index 647be9b02c9..ae831aa10b5 100644 --- a/mysql-test/r/range_vs_index_merge_innodb.result +++ b/mysql-test/r/range_vs_index_merge_innodb.result @@ -1399,4 +1399,66 @@ f5 5 NULL DROP TABLE t1; +CREATE TABLE t1 ( +f1 int, f2 int, f3 int, f4 int, +PRIMARY KEY (f1), KEY (f3), KEY (f4) +); +INSERT INTO t1 VALUES (9,0,2,6), (9930,0,0,NULL); +SET SESSION optimizer_switch='index_merge_intersection=off'; +SET SESSION optimizer_switch='index_merge_sort_union=off'; +SET SESSION optimizer_switch='index_merge_union=off'; +EXPLAIN +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) +WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 +OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL PRIMARY,f3,f4 NULL NULL NULL 2 Using where +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) +WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 +OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); +f1 f2 f3 f4 +9 0 2 6 +SET SESSION optimizer_switch='index_merge_union=on'; +EXPLAIN +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) +WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 +OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge PRIMARY,f3,f4 PRIMARY,f3 4,5 NULL 2 Using union(PRIMARY,f3); Using where +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) +WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 +OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); +f1 f2 f3 f4 +9 0 2 6 +INSERT INTO t1 VALUES +(93,0,3,6), (9933,0,3,3), (94,0,4,6), (9934,0,4,4), +(95,0,5,6), (9935,0,5,5), (96,0,6,6), (9936,0,6,6), +(97,0,7,6), (9937,0,7,7), (98,0,8,6), (9938,0,8,8), +(99,0,9,6), (9939,0,9,9); +SET SESSION optimizer_switch='index_merge_union=off'; +EXPLAIN +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) +WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 +OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL PRIMARY,f3,f4 NULL NULL NULL 16 Using where +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) +WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 +OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); +f1 f2 f3 f4 +9 0 2 6 +SET SESSION optimizer_switch='index_merge_union=on'; +EXPLAIN +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) +WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 +OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge PRIMARY,f3,f4 PRIMARY,f3 4,5 NULL 2 Using union(PRIMARY,f3); Using where +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) +WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 +OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); +f1 f2 f3 f4 +9 0 2 6 +SET SESSION optimizer_switch=DEFAULT; +DROP TABLE t1; SET SESSION STORAGE_ENGINE=DEFAULT; diff --git a/mysql-test/t/range_vs_index_merge.test b/mysql-test/t/range_vs_index_merge.test index 256c5c83ba4..a6dc21bf05a 100755 --- a/mysql-test/t/range_vs_index_merge.test +++ b/mysql-test/t/range_vs_index_merge.test @@ -935,3 +935,71 @@ SELECT f5 FROM t1 DROP TABLE t1; +# +# Bug #685952: An invalid index merge union plan +# + +CREATE TABLE t1 ( + f1 int, f2 int, f3 int, f4 int, + PRIMARY KEY (f1), KEY (f3), KEY (f4) +); + +INSERT INTO t1 VALUES (9,0,2,6), (9930,0,0,NULL); + +SET SESSION optimizer_switch='index_merge_intersection=off'; +SET SESSION optimizer_switch='index_merge_sort_union=off'; + +SET SESSION optimizer_switch='index_merge_union=off'; + +EXPLAIN +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) + WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 + OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); + +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) + WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 + OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); + +SET SESSION optimizer_switch='index_merge_union=on'; + +EXPLAIN +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) + WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 + OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); + +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) + WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 + OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); + + +INSERT INTO t1 VALUES + (93,0,3,6), (9933,0,3,3), (94,0,4,6), (9934,0,4,4), + (95,0,5,6), (9935,0,5,5), (96,0,6,6), (9936,0,6,6), + (97,0,7,6), (9937,0,7,7), (98,0,8,6), (9938,0,8,8), + (99,0,9,6), (9939,0,9,9); + +SET SESSION optimizer_switch='index_merge_union=off'; + +EXPLAIN +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) + WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 + OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); + +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) + WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 + OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); + +SET SESSION optimizer_switch='index_merge_union=on'; + +EXPLAIN +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) + WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 + OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); + +SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4) + WHERE ( f3 = 1 OR f1 = 7 ) AND f1 < 10 + OR f3 BETWEEN 2 AND 2 AND ( f3 = 1 OR f4 != 1 ); + +SET SESSION optimizer_switch=DEFAULT; + +DROP TABLE t1; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 1dded2f1887..6ca9ff5e823 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1081,6 +1081,7 @@ int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param, bool is_first_check_pass, bool *is_last_check_pass) { + bool was_ored= FALSE; *is_last_check_pass= TRUE; SEL_TREE** or_tree = trees; for (uint i= 0; i < n_trees; i++, or_tree++) @@ -1137,9 +1138,11 @@ int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param, *or_tree= result; if (is_first_check_pass) return 0; + else + was_ored= TRUE; } } - if (!is_first_check_pass) + if (was_ored) return 0; if (!*is_last_check_pass && From adb9fd9578f61a73ae224ede3bcb7adef863c1e3 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 7 Dec 2010 14:48:04 -0800 Subject: [PATCH 18/33] Made sure that SELECT from the test case for bug BUG#56862/64041 uses the same execution plan that is in the output of the corresponding EXPLAIN. --- mysql-test/r/index_merge_innodb.result | 2 +- mysql-test/t/index_merge_innodb.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result index 4c561da6420..fdc5b57a2e3 100644 --- a/mysql-test/r/index_merge_innodb.result +++ b/mysql-test/r/index_merge_innodb.result @@ -692,7 +692,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away 2 DERIVED t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 11419 Using sort_union(idx,PRIMARY); Using where SELECT COUNT(*) FROM -(SELECT * FROM t1 +(SELECT * FROM t1 FORCE INDEX(primary,idx) WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; COUNT(*) 6145 diff --git a/mysql-test/t/index_merge_innodb.test b/mysql-test/t/index_merge_innodb.test index 7c6ffaace4f..04f8c5a659b 100644 --- a/mysql-test/t/index_merge_innodb.test +++ b/mysql-test/t/index_merge_innodb.test @@ -71,7 +71,7 @@ SELECT COUNT(*) FROM (SELECT * FROM t1 FORCE INDEX(primary,idx) WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; SELECT COUNT(*) FROM - (SELECT * FROM t1 + (SELECT * FROM t1 FORCE INDEX(primary,idx) WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t; --replace_column 9 # From 93fb6ce1fd8800af73fa630081ff670c49d72b7e Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 7 Dec 2010 19:45:28 -0800 Subject: [PATCH 19/33] The function records_in_index_intersect_extension tried to read after the last element of the array of rec_per_key values for an index. This caused a valgrind complain and probably could result in wrong estimates of the cardinality of index intersections. --- sql/opt_range.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 60b62b05b60..1cd369ddc7d 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -5050,6 +5050,7 @@ ha_rows records_in_index_intersect_extension(PARTIAL_INDEX_INTERSECTION_INFO *cu KEY *key_info= ext_index_scan->key_info; KEY_PART_INFO* key_part= key_info->key_part; KEY_PART_INFO* key_part_end= key_part+ext_index_scan->used_key_parts; + uint key_parts= key_info->key_parts; MY_BITMAP *used_fields= &ext_index_scan->used_fields; if (!curr->length) @@ -5072,7 +5073,7 @@ ha_rows records_in_index_intersect_extension(PARTIAL_INDEX_INTERSECTION_INFO *cu { ulong *rec_per_key= key_info->rec_per_key+i; ulong f1= rec_per_key[0] ? rec_per_key[0] : 1; - ulong f2= rec_per_key[1] ? rec_per_key[1] : 1; + ulong f2= i+1 < key_parts && rec_per_key[1] ? rec_per_key[1] : 1; records= (double) records / f2 * f1; } else From f5a0595209a544ed382216530843d9e85aff4881 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 7 Dec 2010 19:51:48 -0800 Subject: [PATCH 20/33] Corrected the bug number in a test case. --- mysql-test/t/range_vs_index_merge.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/range_vs_index_merge.test b/mysql-test/t/range_vs_index_merge.test index 036d8837d0b..c4b9974879d 100755 --- a/mysql-test/t/range_vs_index_merge.test +++ b/mysql-test/t/range_vs_index_merge.test @@ -926,7 +926,7 @@ SELECT COUNT(*) FROM t1 DROP TABLE t1; # -# Bug #637978: ORing of two index merge that caused a crash +# Bug #684117: ORing of two index merge that caused a crash # CREATE TABLE t1 ( From 1bbb55a2603f3571585cc085f05149d3d9cdbdba Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 8 Dec 2010 14:34:08 +0100 Subject: [PATCH 21/33] MBug#687320: Fix sporadic test failures in innodb_mysql.test and partition_innodb_semi_consistent.test Problem is that these tests run with --innodb-lock-wait-timeout=2 in .opt (and this is necessary as built-in innodb does not allow to change this dynamically). This cases another part of the test to occasionally time out an UPDATE, which subsequently caused the test case to timeout due to waiting for a condition (successful UPDATE) that never occurs. Fixed by re-trying the update in case of timeout. Tested by inserting a sleep() in the connection that the UPDATE is waiting for, and checking that the retry loops a couple of times until the other connection is done and COMMITs. --- mysql-test/include/mix1.inc | 12 +++++++++++- mysql-test/r/partition_innodb_semi_consistent.result | 10 ++++++++++ mysql-test/suite/innodb/r/innodb_mysql.result | 10 ++++++++++ mysql-test/suite/innodb_plugin/r/innodb_mysql.result | 10 ++++++++++ mysql-test/t/partition_innodb_semi_consistent.test | 12 +++++++++++- 5 files changed, 52 insertions(+), 2 deletions(-) diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc index 194d9e41108..7ef8adf8e08 100644 --- a/mysql-test/include/mix1.inc +++ b/mysql-test/include/mix1.inc @@ -1359,7 +1359,17 @@ INSERT INTO t1 VALUES (1,'init'); DELIMITER |; CREATE PROCEDURE p1() BEGIN - UPDATE t1 SET b = CONCAT(b, '+con2') WHERE a = 1; + # retry the UPDATE in case it times out the lock before con1 has time + # to COMMIT. + DECLARE do_retry INT DEFAULT 0; + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET do_retry = 1; + retry_loop:LOOP + UPDATE t1 SET b = CONCAT(b, '+con2') WHERE a = 1; + IF do_retry = 0 THEN + LEAVE retry_loop; + END IF; + SET do_retry = 0; + END LOOP; INSERT INTO t2 VALUES (); END| DELIMITER ;| diff --git a/mysql-test/r/partition_innodb_semi_consistent.result b/mysql-test/r/partition_innodb_semi_consistent.result index 471da4c1c2e..fbdd70528c5 100644 --- a/mysql-test/r/partition_innodb_semi_consistent.result +++ b/mysql-test/r/partition_innodb_semi_consistent.result @@ -75,7 +75,17 @@ TRUNCATE t1; INSERT INTO t1 VALUES (1,'init'); CREATE PROCEDURE p1() BEGIN +# retry the UPDATE in case it times out the lock before con1 has time +# to COMMIT. +DECLARE do_retry INT DEFAULT 0; +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET do_retry = 1; +retry_loop:LOOP UPDATE t1 SET b = CONCAT(b, '+con2') WHERE a = 1; +IF do_retry = 0 THEN +LEAVE retry_loop; +END IF; +SET do_retry = 0; +END LOOP; INSERT INTO t2 VALUES (); END| BEGIN; diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 5d90a96f61c..86a51b337ff 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -1594,7 +1594,17 @@ TRUNCATE t1; INSERT INTO t1 VALUES (1,'init'); CREATE PROCEDURE p1() BEGIN +# retry the UPDATE in case it times out the lock before con1 has time +# to COMMIT. +DECLARE do_retry INT DEFAULT 0; +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET do_retry = 1; +retry_loop:LOOP UPDATE t1 SET b = CONCAT(b, '+con2') WHERE a = 1; +IF do_retry = 0 THEN +LEAVE retry_loop; +END IF; +SET do_retry = 0; +END LOOP; INSERT INTO t2 VALUES (); END| BEGIN; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result index 32ee3c21946..1aee85b5288 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result +++ b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result @@ -1594,7 +1594,17 @@ TRUNCATE t1; INSERT INTO t1 VALUES (1,'init'); CREATE PROCEDURE p1() BEGIN +# retry the UPDATE in case it times out the lock before con1 has time +# to COMMIT. +DECLARE do_retry INT DEFAULT 0; +DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET do_retry = 1; +retry_loop:LOOP UPDATE t1 SET b = CONCAT(b, '+con2') WHERE a = 1; +IF do_retry = 0 THEN +LEAVE retry_loop; +END IF; +SET do_retry = 0; +END LOOP; INSERT INTO t2 VALUES (); END| BEGIN; diff --git a/mysql-test/t/partition_innodb_semi_consistent.test b/mysql-test/t/partition_innodb_semi_consistent.test index 2711d79f194..9d3e2570256 100644 --- a/mysql-test/t/partition_innodb_semi_consistent.test +++ b/mysql-test/t/partition_innodb_semi_consistent.test @@ -117,7 +117,17 @@ INSERT INTO t1 VALUES (1,'init'); DELIMITER |; CREATE PROCEDURE p1() BEGIN - UPDATE t1 SET b = CONCAT(b, '+con2') WHERE a = 1; + # retry the UPDATE in case it times out the lock before con1 has time + # to COMMIT. + DECLARE do_retry INT DEFAULT 0; + DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET do_retry = 1; + retry_loop:LOOP + UPDATE t1 SET b = CONCAT(b, '+con2') WHERE a = 1; + IF do_retry = 0 THEN + LEAVE retry_loop; + END IF; + SET do_retry = 0; + END LOOP; INSERT INTO t2 VALUES (); END| DELIMITER ;| From afcefa97d9f814a20d97a1f8d2995bcd1633e1f2 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 9 Dec 2010 11:06:32 -0800 Subject: [PATCH 22/33] Addemdum for bug #685952. Also: Changed the value of TIME_FOR_COMPARE_ROWID to make it the same as for MWL 21. Changed some queries in range_vs_index_merge.test to make them generate the same plans as earlier. --- mysql-test/include/index_merge1.inc | 2 +- mysql-test/r/index_merge_myisam.result | 4 +- mysql-test/r/range_vs_index_merge.result | 186 +++++------------ .../r/range_vs_index_merge_innodb.result | 190 +++++------------- mysql-test/t/range_vs_index_merge.test | 54 ++--- sql/mysql_priv.h | 2 +- sql/opt_range.cc | 5 +- 7 files changed, 129 insertions(+), 314 deletions(-) diff --git a/mysql-test/include/index_merge1.inc b/mysql-test/include/index_merge1.inc index b3e61802dcf..5cd7bec1895 100644 --- a/mysql-test/include/index_merge1.inc +++ b/mysql-test/include/index_merge1.inc @@ -194,7 +194,7 @@ alter table t2 add index i321(key3, key2, key1); explain select key3 from t2 where key1 = 100 or key2 = 100; # index_merge vs 'index', 'index' is better. -explain select key3 from t2 where key1 <100 or key2 < 100; +explain select key3 from t2 where key1 < 500 or key2 < 500; # index_merge vs 'all', index_merge is better. explain select key7 from t2 where key1 <100 or key2 < 100; diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result index db0b4abb7d5..dd65b56014f 100644 --- a/mysql-test/r/index_merge_myisam.result +++ b/mysql-test/r/index_merge_myisam.result @@ -203,12 +203,12 @@ alter table t2 add index i321(key3, key2, key1); explain select key3 from t2 where key1 = 100 or key2 = 100; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index_merge i1_3,i2_3 i1_3,i2_3 4,4 NULL 2 Using sort_union(i1_3,i2_3); Using where -explain select key3 from t2 where key1 <100 or key2 < 100; +explain select key3 from t2 where key1 < 500 or key2 < 500; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index i1_3,i2_3 i321 12 NULL 1024 Using where; Using index explain select key7 from t2 where key1 <100 or key2 < 100; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL i1_3,i2_3 NULL NULL NULL 1024 Using where +1 SIMPLE t2 index_merge i1_3,i2_3 i1_3,i2_3 4,4 NULL 188 Using sort_union(i1_3,i2_3); Using where create table t4 ( key1a int not null, key1b int not null, diff --git a/mysql-test/r/range_vs_index_merge.result b/mysql-test/r/range_vs_index_merge.result index dccb2e3b836..5ad4a5b1571 100644 --- a/mysql-test/r/range_vs_index_merge.result +++ b/mysql-test/r/range_vs_index_merge.result @@ -71,9 +71,9 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Population Population 4 NULL 459 Using where EXPLAIN SELECT * FROM City -WHERE (Population > 101000 AND Population < 103000); +WHERE (Population > 101000 AND Population < 102000); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population Population 4 NULL 81 Using where +1 SIMPLE City range Population Population 4 NULL 39 Using where EXPLAIN SELECT * FROM City WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')); @@ -88,9 +88,9 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) -AND (Population > 101000 AND Population < 103000); +AND (Population > 101000 AND Population < 102000); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Country,Name Population 4 NULL 81 Using where +1 SIMPLE City range Population,Country,Name Population 4 NULL 39 Using where SELECT * FROM City USE INDEX () WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) AND (Population > 101000 AND Population < 115000); @@ -153,24 +153,20 @@ ID Name Country Population 4032 Cambridge USA 101355 SELECT * FROM City USE INDEX () WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) -AND (Population > 101000 AND Population < 103000); +AND (Population > 101000 AND Population < 102000); ID Name Country Population 637 Mit Ghamr EGY 101801 707 Marbella ESP 101144 -3411 Ceyhan TUR 102412 3792 Tartu EST 101246 -4027 Cape Coral USA 102286 4032 Cambridge USA 101355 SELECT * FROM City WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) -AND (Population > 101000 AND Population < 103000); +AND (Population > 101000 AND Population < 102000); ID Name Country Population 707 Marbella ESP 101144 3792 Tartu EST 101246 4032 Cambridge USA 101355 637 Mit Ghamr EGY 101801 -4027 Cape Coral USA 102286 -3411 Ceyhan TUR 102412 EXPLAIN SELECT * FROM City WHERE (Name < 'Ac'); id select_type table type possible_keys key key_len ref rows Extra @@ -328,15 +324,15 @@ ID Name Country Population 1003 Pemalang IDN 103500 2663 Río Bravo MEX 103901 EXPLAIN -SELECT * FROM City WHERE (ID < 50) OR (ID BETWEEN 100 AND 110); +SELECT * FROM City WHERE (ID < 10) OR (ID BETWEEN 100 AND 110); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 61 Using where +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 21 Using where EXPLAIN -SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 300 AND 600); +SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 100 AND 200); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 501 Using where +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 201 Using where EXPLAIN -SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1800); +SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1500); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City ALL PRIMARY NULL NULL NULL 4079 Using where EXPLAIN @@ -353,27 +349,27 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Name Name 35 NULL 72 Using where EXPLAIN SELECT * FROM City -WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) +WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 61 Using where +1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 21 Using where EXPLAIN SELECT * FROM City WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) -OR ((ID BETWEEN 900 AND 1800) AND +OR ((ID BETWEEN 900 AND 1500) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,Population 35,3,4 NULL 128 Using sort_union(Name,Country,Population); Using where EXPLAIN SELECT * FROM City -WHERE ((ID < 600) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) -OR ((ID BETWEEN 300 AND 600) AND +WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 100 AND 200) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,Population 35,3,4 NULL 128 Using sort_union(Name,Country,Population); Using where SELECT * FROM City USE INDEX () -WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) +WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); ID Name Country Population @@ -382,15 +378,10 @@ ID Name Country Population 3 Herat AFG 186800 4 Mazar-e-Sharif AFG 127800 7 Haag NLD 440900 -16 Haarlem NLD 148772 -25 Haarlemmermeer NLD 110722 -31 Heerlen NLD 95052 -33 Willemstad ANT 2345 -34 Tirana ALB 270000 100 Paraná ARG 207041 102 Posadas ARG 201273 SELECT * FROM City -WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) +WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); ID Name Country Population @@ -399,16 +390,11 @@ ID Name Country Population 3 Herat AFG 186800 4 Mazar-e-Sharif AFG 127800 7 Haag NLD 440900 -16 Haarlem NLD 148772 -25 Haarlemmermeer NLD 110722 -31 Heerlen NLD 95052 -33 Willemstad ANT 2345 -34 Tirana ALB 270000 100 Paraná ARG 207041 102 Posadas ARG 201273 SELECT * FROM City USE INDEX() WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) -OR ((ID BETWEEN 900 AND 1800) AND +OR ((ID BETWEEN 900 AND 1500) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); ID Name Country Population 1 Kabul AFG 1780000 @@ -463,13 +449,9 @@ ID Name Country Population 1468 Palermo ITA 683794 1478 Padova ITA 211391 1484 Parma ITA 168717 -1530 Kingston JAM 103962 -1747 Toda JPN 103969 -1748 Tajimi JPN 103171 -1785 Ibb YEM 103300 SELECT * FROM City WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) -OR ((ID BETWEEN 900 AND 1800) AND +OR ((ID BETWEEN 900 AND 1500) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); ID Name Country Population 1 Kabul AFG 1780000 @@ -524,13 +506,9 @@ ID Name Country Population 1468 Palermo ITA 683794 1478 Padova ITA 211391 1484 Parma ITA 168717 -1530 Kingston JAM 103962 -1747 Toda JPN 103969 -1748 Tajimi JPN 103171 -1785 Ibb YEM 103300 SELECT * FROM City USE INDEX () WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) -OR ((ID BETWEEN 300 AND 600) AND +OR ((ID BETWEEN 100 AND 200) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); ID Name Country Population 1 Kabul AFG 1780000 @@ -555,25 +533,15 @@ ID Name Country Population 66 Sharja ARE 320095 67 al-Ayn ARE 225970 68 Ajman ARE 114395 +100 Paraná ARG 207041 129 Oranjestad ABW 29034 +167 Jamalpur BGD 103556 +168 Pabna BGD 103277 +189 Parakou BEN 103577 191 Hamilton BMU 1200 -339 Passo Fundo BRA 166343 -364 Parnaíba BRA 129756 -372 Paranaguá BRA 126076 -379 Palmas BRA 121919 -386 Patos de Minas BRA 119262 -411 Guaratinguetá BRA 103433 -412 Cachoeirinha BRA 103240 -413 Codó BRA 103153 -424 Passos BRA 98570 -430 Paulo Afonso BRA 97291 -435 Parnamirim BRA 96210 -448 Patos BRA 90519 -451 Palhoça BRA 89465 -517 Oldham GBR 103931 SELECT * FROM City WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) -OR ((ID BETWEEN 300 AND 600) AND +OR ((ID BETWEEN 100 AND 200) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); ID Name Country Population 1 Kabul AFG 1780000 @@ -598,22 +566,12 @@ ID Name Country Population 66 Sharja ARE 320095 67 al-Ayn ARE 225970 68 Ajman ARE 114395 +100 Paraná ARG 207041 129 Oranjestad ABW 29034 +167 Jamalpur BGD 103556 +168 Pabna BGD 103277 +189 Parakou BEN 103577 191 Hamilton BMU 1200 -339 Passo Fundo BRA 166343 -364 Parnaíba BRA 129756 -372 Paranaguá BRA 126076 -379 Palmas BRA 121919 -386 Patos de Minas BRA 119262 -411 Guaratinguetá BRA 103433 -412 Cachoeirinha BRA 103240 -413 Codó BRA 103153 -424 Passos BRA 98570 -430 Paulo Afonso BRA 97291 -435 Parnamirim BRA 96210 -448 Patos BRA 90519 -451 Palhoça BRA 89465 -517 Oldham GBR 103931 EXPLAIN SELECT * FROM City WHERE Population > 101000 AND Population < 102000; id select_type table type possible_keys key key_len ref rows Extra @@ -734,6 +692,10 @@ SELECT * FROM City WHERE Country='USA'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City ref Country,CountryPopulation Country 3 const 267 Using where EXPLAIN +SELECT * FROM City WHERE Country='FIN'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ref Country,CountryPopulation Country 3 const 6 Using where +EXPLAIN SELECT * FROM City WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') AND Country='USA'; @@ -742,9 +704,9 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') -AND Country='USA'; +AND Country='FIN'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City ref Population,Country,Name,CountryPopulation Country 3 const 267 Using where +1 SIMPLE City ref Population,Country,Name,CountryPopulation Country 3 const 6 Using where SELECT * FROM City WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') AND Country='USA'; @@ -779,72 +741,22 @@ ID Name Country Population 4032 Cambridge USA 101355 SELECT * FROM City WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') -AND Country='USA'; +AND Country='FIN'; ID Name Country Population -3797 Philadelphia USA 1517550 -3798 Phoenix USA 1321045 -3820 Portland USA 529121 -3844 Pittsburgh USA 334563 -3870 Plano USA 222030 -3912 Providence USA 173618 -3930 Pomona USA 149473 -3932 Paterson USA 149222 -3943 Pasadena USA 141674 -3951 Pembroke Pines USA 137427 -3953 Pasadena USA 133936 -3967 Paradise USA 124682 -3986 Palmdale USA 116670 -3996 Peoria USA 112936 -4007 Peoria USA 108364 -4016 Provo USA 105166 -4023 Gary USA 102746 -4024 Berkeley USA 102743 -4025 Santa Clara USA 102361 -4026 Green Bay USA 102313 -4027 Cape Coral USA 102286 -4028 Arvada USA 102153 -4029 Pueblo USA 102121 -4030 Sandy USA 101853 -4031 Athens-Clarke County USA 101489 -4032 Cambridge USA 101355 -4035 Portsmouth USA 100565 SELECT * FROM City USE INDEX () WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') -AND Country='USA'; +AND Country='FIN'; ID Name Country Population -3797 Philadelphia USA 1517550 -3798 Phoenix USA 1321045 -3820 Portland USA 529121 -3844 Pittsburgh USA 334563 -3870 Plano USA 222030 -3912 Providence USA 173618 -3930 Pomona USA 149473 -3932 Paterson USA 149222 -3943 Pasadena USA 141674 -3951 Pembroke Pines USA 137427 -3953 Pasadena USA 133936 -3967 Paradise USA 124682 -3986 Palmdale USA 116670 -3996 Peoria USA 112936 -4007 Peoria USA 108364 -4016 Provo USA 105166 -4023 Gary USA 102746 -4024 Berkeley USA 102743 -4025 Santa Clara USA 102361 -4026 Green Bay USA 102313 -4027 Cape Coral USA 102286 -4028 Arvada USA 102153 -4029 Pueblo USA 102121 -4030 Sandy USA 101853 -4031 Athens-Clarke County USA 101489 -4032 Cambridge USA 101355 -4035 Portsmouth USA 100565 CREATE INDEX CountryName ON City(Country,Name); EXPLAIN SELECT * FROM City WHERE Country='USA'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 267 Using where EXPLAIN +SELECT * FROM City WHERE Country='FIN'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ref Country,CountryPopulation,CountryName CountryName 3 const 5 Using where +EXPLAIN SELECT * FROM City WHERE Country='BRA'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City ref Country,CountryPopulation,CountryName CountryName 3 const 221 Using where @@ -901,10 +813,10 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE ((Population > 101000 AND Population < 110000) OR -ID BETWEEN 3500 AND 3800) AND Country='USA' +ID BETWEEN 3500 AND 3800) AND Country='FIN' AND (Name BETWEEN 'P' AND 'T' OR ID BETWEEN 4000 AND 4300); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City ref PRIMARY,Population,Country,Name,CountryPopulation,CountryName Country 3 const 267 Using where +1 SIMPLE City ref PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName 3 const 5 Using where SELECT * FROM City USE INDEX () WHERE ((Population > 101000 AND Population < 102000) OR ID BETWEEN 3790 AND 3800) AND Country='USA' @@ -939,20 +851,14 @@ ID Name Country Population 4032 Cambridge USA 101355 SELECT * FROM City USE INDEX () WHERE ((Population > 101000 AND Population < 102000) OR -ID BETWEEN 3790 AND 3800) AND Country='USA' +ID BETWEEN 3790 AND 3800) AND Country='FIN' AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); ID Name Country Population -4030 Sandy USA 101853 -4031 Athens-Clarke County USA 101489 -4032 Cambridge USA 101355 SELECT * FROM City WHERE ((Population > 101000 AND Population < 102000) OR -ID BETWEEN 3790 AND 3800) AND Country='USA' +ID BETWEEN 3790 AND 3800) AND Country='FIN' AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); ID Name Country Population -4030 Sandy USA 101853 -4031 Athens-Clarke County USA 101489 -4032 Cambridge USA 101355 EXPLAIN SELECT * FROM City WHERE ((Population > 101000 and Population < 102000) OR diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result index ae831aa10b5..75737de8942 100644 --- a/mysql-test/r/range_vs_index_merge_innodb.result +++ b/mysql-test/r/range_vs_index_merge_innodb.result @@ -72,9 +72,9 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Population Population 4 NULL 458 Using where EXPLAIN SELECT * FROM City -WHERE (Population > 101000 AND Population < 103000); +WHERE (Population > 101000 AND Population < 102000); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population Population 4 NULL 80 Using where +1 SIMPLE City range Population Population 4 NULL 38 Using where EXPLAIN SELECT * FROM City WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')); @@ -89,9 +89,9 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) -AND (Population > 101000 AND Population < 103000); +AND (Population > 101000 AND Population < 102000); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range Population,Country,Name Population 4 NULL 80 Using where +1 SIMPLE City range Population,Country,Name Population 4 NULL 38 Using where SELECT * FROM City USE INDEX () WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) AND (Population > 101000 AND Population < 115000); @@ -154,24 +154,20 @@ ID Name Country Population 4032 Cambridge USA 101355 SELECT * FROM City USE INDEX () WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) -AND (Population > 101000 AND Population < 103000); +AND (Population > 101000 AND Population < 102000); ID Name Country Population 637 Mit Ghamr EGY 101801 707 Marbella ESP 101144 -3411 Ceyhan TUR 102412 3792 Tartu EST 101246 -4027 Cape Coral USA 102286 4032 Cambridge USA 101355 SELECT * FROM City WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) -AND (Population > 101000 AND Population < 103000); +AND (Population > 101000 AND Population < 102000); ID Name Country Population 707 Marbella ESP 101144 3792 Tartu EST 101246 4032 Cambridge USA 101355 637 Mit Ghamr EGY 101801 -4027 Cape Coral USA 102286 -3411 Ceyhan TUR 102412 EXPLAIN SELECT * FROM City WHERE (Name < 'Ac'); id select_type table type possible_keys key key_len ref rows Extra @@ -329,17 +325,17 @@ ID Name Country Population 1003 Pemalang IDN 103500 2663 Río Bravo MEX 103901 EXPLAIN -SELECT * FROM City WHERE (ID < 50) OR (ID BETWEEN 100 AND 110); +SELECT * FROM City WHERE (ID < 10) OR (ID BETWEEN 100 AND 110); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 60 Using where +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 20 Using where EXPLAIN -SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 300 AND 600); +SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 100 AND 200); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 1142 Using where +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 199 Using where EXPLAIN -SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1800); +SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1500); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 2950 Using where +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 2006 Using where EXPLAIN SELECT * FROM City WHERE Country > 'A' AND Country < 'ARG'; id select_type table type possible_keys key key_len ref rows Extra @@ -354,27 +350,27 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City range Name Name 35 NULL 133 Using where EXPLAIN SELECT * FROM City -WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) +WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 60 Using where +1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 20 Using where EXPLAIN SELECT * FROM City WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) -OR ((ID BETWEEN 900 AND 1800) AND +OR ((ID BETWEEN 900 AND 1500) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,Population 35,3,4 NULL 188 Using sort_union(Name,Country,Population); Using where EXPLAIN SELECT * FROM City -WHERE ((ID < 600) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) -OR ((ID BETWEEN 300 AND 600) AND +WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) +OR ((ID BETWEEN 100 AND 200) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 1242 Using where +1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 199 Using where SELECT * FROM City USE INDEX () -WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) +WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); ID Name Country Population @@ -383,15 +379,10 @@ ID Name Country Population 3 Herat AFG 186800 4 Mazar-e-Sharif AFG 127800 7 Haag NLD 440900 -16 Haarlem NLD 148772 -25 Haarlemmermeer NLD 110722 -31 Heerlen NLD 95052 -33 Willemstad ANT 2345 -34 Tirana ALB 270000 100 Paraná ARG 207041 102 Posadas ARG 201273 SELECT * FROM City -WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) +WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); ID Name Country Population @@ -400,16 +391,11 @@ ID Name Country Population 3 Herat AFG 186800 4 Mazar-e-Sharif AFG 127800 7 Haag NLD 440900 -16 Haarlem NLD 148772 -25 Haarlemmermeer NLD 110722 -31 Heerlen NLD 95052 -33 Willemstad ANT 2345 -34 Tirana ALB 270000 100 Paraná ARG 207041 102 Posadas ARG 201273 SELECT * FROM City USE INDEX() WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) -OR ((ID BETWEEN 900 AND 1800) AND +OR ((ID BETWEEN 900 AND 1500) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); ID Name Country Population 1 Kabul AFG 1780000 @@ -464,13 +450,9 @@ ID Name Country Population 1468 Palermo ITA 683794 1478 Padova ITA 211391 1484 Parma ITA 168717 -1530 Kingston JAM 103962 -1747 Toda JPN 103969 -1748 Tajimi JPN 103171 -1785 Ibb YEM 103300 SELECT * FROM City WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) -OR ((ID BETWEEN 900 AND 1800) AND +OR ((ID BETWEEN 900 AND 1500) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); ID Name Country Population 1 Kabul AFG 1780000 @@ -525,13 +507,9 @@ ID Name Country Population 1468 Palermo ITA 683794 1478 Padova ITA 211391 1484 Parma ITA 168717 -1530 Kingston JAM 103962 -1747 Toda JPN 103969 -1748 Tajimi JPN 103171 -1785 Ibb YEM 103300 SELECT * FROM City USE INDEX () WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) -OR ((ID BETWEEN 300 AND 600) AND +OR ((ID BETWEEN 100 AND 200) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); ID Name Country Population 1 Kabul AFG 1780000 @@ -556,25 +534,15 @@ ID Name Country Population 66 Sharja ARE 320095 67 al-Ayn ARE 225970 68 Ajman ARE 114395 +100 Paraná ARG 207041 129 Oranjestad ABW 29034 +167 Jamalpur BGD 103556 +168 Pabna BGD 103277 +189 Parakou BEN 103577 191 Hamilton BMU 1200 -339 Passo Fundo BRA 166343 -364 Parnaíba BRA 129756 -372 Paranaguá BRA 126076 -379 Palmas BRA 121919 -386 Patos de Minas BRA 119262 -411 Guaratinguetá BRA 103433 -412 Cachoeirinha BRA 103240 -413 Codó BRA 103153 -424 Passos BRA 98570 -430 Paulo Afonso BRA 97291 -435 Parnamirim BRA 96210 -448 Patos BRA 90519 -451 Palhoça BRA 89465 -517 Oldham GBR 103931 SELECT * FROM City WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) -OR ((ID BETWEEN 300 AND 600) AND +OR ((ID BETWEEN 100 AND 200) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); ID Name Country Population 1 Kabul AFG 1780000 @@ -599,22 +567,12 @@ ID Name Country Population 66 Sharja ARE 320095 67 al-Ayn ARE 225970 68 Ajman ARE 114395 +100 Paraná ARG 207041 129 Oranjestad ABW 29034 +167 Jamalpur BGD 103556 +168 Pabna BGD 103277 +189 Parakou BEN 103577 191 Hamilton BMU 1200 -339 Passo Fundo BRA 166343 -364 Parnaíba BRA 129756 -372 Paranaguá BRA 126076 -379 Palmas BRA 121919 -386 Patos de Minas BRA 119262 -411 Guaratinguetá BRA 103433 -412 Cachoeirinha BRA 103240 -413 Codó BRA 103153 -424 Passos BRA 98570 -430 Paulo Afonso BRA 97291 -435 Parnamirim BRA 96210 -448 Patos BRA 90519 -451 Palhoça BRA 89465 -517 Oldham GBR 103931 EXPLAIN SELECT * FROM City WHERE Population > 101000 AND Population < 102000; id select_type table type possible_keys key key_len ref rows Extra @@ -735,6 +693,10 @@ SELECT * FROM City WHERE Country='USA'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City ref Country,CountryPopulation Country 3 const 274 Using where EXPLAIN +SELECT * FROM City WHERE Country='FIN'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ref Country,CountryPopulation Country 3 const 7 Using where +EXPLAIN SELECT * FROM City WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') AND Country='USA'; @@ -743,9 +705,9 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') -AND Country='USA'; +AND Country='FIN'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City ref Population,Country,Name,CountryPopulation Country 3 const 274 Using where +1 SIMPLE City ref Population,Country,Name,CountryPopulation Country 3 const 7 Using where SELECT * FROM City WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%') AND Country='USA'; @@ -780,72 +742,22 @@ ID Name Country Population 4032 Cambridge USA 101355 SELECT * FROM City WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') -AND Country='USA'; +AND Country='FIN'; ID Name Country Population -3797 Philadelphia USA 1517550 -3798 Phoenix USA 1321045 -3820 Portland USA 529121 -3844 Pittsburgh USA 334563 -3870 Plano USA 222030 -3912 Providence USA 173618 -3930 Pomona USA 149473 -3932 Paterson USA 149222 -3943 Pasadena USA 141674 -3951 Pembroke Pines USA 137427 -3953 Pasadena USA 133936 -3967 Paradise USA 124682 -3986 Palmdale USA 116670 -3996 Peoria USA 112936 -4007 Peoria USA 108364 -4016 Provo USA 105166 -4023 Gary USA 102746 -4024 Berkeley USA 102743 -4025 Santa Clara USA 102361 -4026 Green Bay USA 102313 -4027 Cape Coral USA 102286 -4028 Arvada USA 102153 -4029 Pueblo USA 102121 -4030 Sandy USA 101853 -4031 Athens-Clarke County USA 101489 -4032 Cambridge USA 101355 -4035 Portsmouth USA 100565 SELECT * FROM City USE INDEX () WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') -AND Country='USA'; +AND Country='FIN'; ID Name Country Population -3797 Philadelphia USA 1517550 -3798 Phoenix USA 1321045 -3820 Portland USA 529121 -3844 Pittsburgh USA 334563 -3870 Plano USA 222030 -3912 Providence USA 173618 -3930 Pomona USA 149473 -3932 Paterson USA 149222 -3943 Pasadena USA 141674 -3951 Pembroke Pines USA 137427 -3953 Pasadena USA 133936 -3967 Paradise USA 124682 -3986 Palmdale USA 116670 -3996 Peoria USA 112936 -4007 Peoria USA 108364 -4016 Provo USA 105166 -4023 Gary USA 102746 -4024 Berkeley USA 102743 -4025 Santa Clara USA 102361 -4026 Green Bay USA 102313 -4027 Cape Coral USA 102286 -4028 Arvada USA 102153 -4029 Pueblo USA 102121 -4030 Sandy USA 101853 -4031 Athens-Clarke County USA 101489 -4032 Cambridge USA 101355 -4035 Portsmouth USA 100565 CREATE INDEX CountryName ON City(Country,Name); EXPLAIN SELECT * FROM City WHERE Country='USA'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 274 Using where EXPLAIN +SELECT * FROM City WHERE Country='FIN'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 7 Using where +EXPLAIN SELECT * FROM City WHERE Country='BRA'; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE City ref Country,CountryPopulation,CountryName Country 3 const 250 Using where @@ -902,10 +814,10 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE ((Population > 101000 AND Population < 110000) OR -ID BETWEEN 3500 AND 3800) AND Country='USA' +ID BETWEEN 3500 AND 3800) AND Country='FIN' AND (Name BETWEEN 'P' AND 'T' OR ID BETWEEN 4000 AND 4300); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City ref PRIMARY,Population,Country,Name,CountryPopulation,CountryName Country 3 const 274 Using where +1 SIMPLE City ref PRIMARY,Population,Country,Name,CountryPopulation,CountryName Country 3 const 7 Using where SELECT * FROM City USE INDEX () WHERE ((Population > 101000 AND Population < 102000) OR ID BETWEEN 3790 AND 3800) AND Country='USA' @@ -940,20 +852,14 @@ ID Name Country Population 4032 Cambridge USA 101355 SELECT * FROM City USE INDEX () WHERE ((Population > 101000 AND Population < 102000) OR -ID BETWEEN 3790 AND 3800) AND Country='USA' +ID BETWEEN 3790 AND 3800) AND Country='FIN' AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); ID Name Country Population -4030 Sandy USA 101853 -4031 Athens-Clarke County USA 101489 -4032 Cambridge USA 101355 SELECT * FROM City WHERE ((Population > 101000 AND Population < 102000) OR -ID BETWEEN 3790 AND 3800) AND Country='USA' +ID BETWEEN 3790 AND 3800) AND Country='FIN' AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); ID Name Country Population -4030 Sandy USA 101853 -4031 Athens-Clarke County USA 101489 -4032 Cambridge USA 101355 EXPLAIN SELECT * FROM City WHERE ((Population > 101000 and Population < 102000) OR diff --git a/mysql-test/t/range_vs_index_merge.test b/mysql-test/t/range_vs_index_merge.test index a6dc21bf05a..19ecb45c531 100755 --- a/mysql-test/t/range_vs_index_merge.test +++ b/mysql-test/t/range_vs_index_merge.test @@ -68,7 +68,7 @@ SELECT * FROM City EXPLAIN SELECT * FROM City - WHERE (Population > 101000 AND Population < 103000); + WHERE (Population > 101000 AND Population < 102000); EXPLAIN SELECT * FROM City @@ -88,7 +88,7 @@ SELECT * FROM City EXPLAIN SELECT * FROM City WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) - AND (Population > 101000 AND Population < 103000); + AND (Population > 101000 AND Population < 102000); # The following 4 queries check that the plans # for the previous 2 plans are valid @@ -103,11 +103,11 @@ SELECT * FROM City SELECT * FROM City USE INDEX () WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) - AND (Population > 101000 AND Population < 103000); + AND (Population > 101000 AND Population < 102000); SELECT * FROM City WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F')) - AND (Population > 101000 AND Population < 103000); + AND (Population > 101000 AND Population < 102000); # The output of the next 7 commands tells us about selectivities # of the conditions utilized in 4 queries following after them @@ -197,11 +197,11 @@ SELECT * FROM City # of the conditions utilized in 3 queries following after them EXPLAIN -SELECT * FROM City WHERE (ID < 50) OR (ID BETWEEN 100 AND 110); +SELECT * FROM City WHERE (ID < 10) OR (ID BETWEEN 100 AND 110); EXPLAIN -SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 300 AND 600); +SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 100 AND 200); EXPLAIN -SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1800); +SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1500); EXPLAIN SELECT * FROM City WHERE Country > 'A' AND Country < 'ARG'; EXPLAIN @@ -219,20 +219,20 @@ SELECT * FROM City WHERE Name LIKE 'Ha%' OR Name LIKE 'Pa%' ; EXPLAIN SELECT * FROM City - WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) + WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); EXPLAIN SELECT * FROM City WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) - OR ((ID BETWEEN 900 AND 1800) AND + OR ((ID BETWEEN 900 AND 1500) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); EXPLAIN SELECT * FROM City - WHERE ((ID < 600) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) - OR ((ID BETWEEN 300 AND 600) AND + WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) + OR ((ID BETWEEN 100 AND 200) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); @@ -240,33 +240,33 @@ SELECT * FROM City # for the previous 3 plans are valid SELECT * FROM City USE INDEX () - WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) + WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); SELECT * FROM City - WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) + WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); SELECT * FROM City USE INDEX() WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) - OR ((ID BETWEEN 900 AND 1800) AND + OR ((ID BETWEEN 900 AND 1500) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); SELECT * FROM City WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) - OR ((ID BETWEEN 900 AND 1800) AND + OR ((ID BETWEEN 900 AND 1500) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); SELECT * FROM City USE INDEX () WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) - OR ((ID BETWEEN 300 AND 600) AND + OR ((ID BETWEEN 100 AND 200) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); SELECT * FROM City WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) - OR ((ID BETWEEN 300 AND 600) AND + OR ((ID BETWEEN 100 AND 200) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); @@ -353,7 +353,7 @@ ANALYZE TABLE City; --enable_result_log --enable_query_log -# The output of the next 4 commands tells us about selectivities +# The output of the next 5 commands tells us about selectivities # of the conditions utilized in 2 queries following after them EXPLAIN @@ -364,6 +364,8 @@ EXPLAIN SELECT * FROM City WHERE (Population > 101000 AND Population < 103000); EXPLAIN SELECT * FROM City WHERE Country='USA'; +EXPLAIN +SELECT * FROM City WHERE Country='FIN'; # The pattern of the WHERE condition used in the following 3 queries is # (range(key1_p2) OR (range(key2)) AND key1_p1=c @@ -380,7 +382,7 @@ SELECT * FROM City EXPLAIN SELECT * FROM City WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') - AND Country='USA'; + AND Country='FIN'; # The following 4 queries check that the plans # for the previous 2 plans are valid @@ -395,11 +397,11 @@ SELECT * FROM City USE INDEX () SELECT * FROM City WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') - AND Country='USA'; + AND Country='FIN'; SELECT * FROM City USE INDEX () WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%') - AND Country='USA'; + AND Country='FIN'; CREATE INDEX CountryName ON City(Country,Name); @@ -412,12 +414,14 @@ ANALYZE TABLE City; --enable_result_log --enable_query_log -# The output of the next 11 commands tells us about selectivities +# The output of the next 12 commands tells us about selectivities # of the conditions utilized in 3 queries following after them EXPLAIN SELECT * FROM City WHERE Country='USA'; EXPLAIN +SELECT * FROM City WHERE Country='FIN'; +EXPLAIN SELECT * FROM City WHERE Country='BRA'; EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800; @@ -464,7 +468,7 @@ SELECT * FROM City EXPLAIN SELECT * FROM City WHERE ((Population > 101000 AND Population < 110000) OR - ID BETWEEN 3500 AND 3800) AND Country='USA' + ID BETWEEN 3500 AND 3800) AND Country='FIN' AND (Name BETWEEN 'P' AND 'T' OR ID BETWEEN 4000 AND 4300); # The following 6 queries check that the plans @@ -492,12 +496,12 @@ SELECT * FROM City SELECT * FROM City USE INDEX () WHERE ((Population > 101000 AND Population < 102000) OR - ID BETWEEN 3790 AND 3800) AND Country='USA' + ID BETWEEN 3790 AND 3800) AND Country='FIN' AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); SELECT * FROM City WHERE ((Population > 101000 AND Population < 102000) OR - ID BETWEEN 3790 AND 3800) AND Country='USA' + ID BETWEEN 3790 AND 3800) AND Country='FIN' AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 7905a0f52e5..274b4d71cea 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -338,7 +338,7 @@ protected: Number of comparisons of table rowids equivalent to reading one row from a table. */ -#define TIME_FOR_COMPARE_ROWID (TIME_FOR_COMPARE*2) +#define TIME_FOR_COMPARE_ROWID (TIME_FOR_COMPARE*100) /* For sequential disk seeks the cost formula is: diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 6ca9ff5e823..2435492061e 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1093,7 +1093,7 @@ int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param, { bool must_be_ored= sel_trees_must_be_ored(param, *or_tree, tree, ored_keys); - if (must_be_ored == is_first_check_pass) + if (must_be_ored || !is_first_check_pass) { result_keys.clear_all(); result= *or_tree; @@ -1138,8 +1138,7 @@ int SEL_IMERGE::or_sel_tree_with_checks(RANGE_OPT_PARAM *param, *or_tree= result; if (is_first_check_pass) return 0; - else - was_ored= TRUE; + was_ored= TRUE; } } if (was_ored) From b78f6240448c3e53ae60549483eb78225a5edc34 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 10 Dec 2010 09:51:34 +0100 Subject: [PATCH 23/33] Fix wrong merge of patch for Bug#46639. --- sql/ha_partition.cc | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index e7de3fb5289..e2ad4b4462c 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -4640,19 +4640,6 @@ int ha_partition::handle_unordered_scan_next_partition(uchar * buf) break; case partition_index_first: DBUG_PRINT("info", ("index_first on partition %d", i)); - /* - MyISAM engine can fail if we call index_first() when indexes disabled - that happens if the table is empty. - Here we use file->stats.records instead of file->records() because - file->records() is supposed to return an EXACT count, and it can be - possibly slow. We don't need an exact number, an approximate one- from - the last ::info() call - is sufficient. - */ - if (file->stats.records == 0) - { - error= HA_ERR_END_OF_FILE; - break; - } error= file->ha_index_first(buf); break; case partition_index_first_unordered: @@ -4740,36 +4727,10 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order) m_start_key.flag); break; case partition_index_first: - /* - MyISAM engine can fail if we call index_first() when indexes disabled - that happens if the table is empty. - Here we use file->stats.records instead of file->records() because - file->records() is supposed to return an EXACT count, and it can be - possibly slow. We don't need an exact number, an approximate one- from - the last ::info() call - is sufficient. - */ - if (file->stats.records == 0) - { - error= HA_ERR_END_OF_FILE; - break; - } error= file->ha_index_first(rec_buf_ptr); reverse_order= FALSE; break; case partition_index_last: - /* - MyISAM engine can fail if we call index_last() when indexes disabled - that happens if the table is empty. - Here we use file->stats.records instead of file->records() because - file->records() is supposed to return an EXACT count, and it can be - possibly slow. We don't need an exact number, an approximate one- from - the last ::info() call - is sufficient. - */ - if (file->stats.records == 0) - { - error= HA_ERR_END_OF_FILE; - break; - } error= file->ha_index_last(rec_buf_ptr); reverse_order= TRUE; break; From 84edaac4f14b2fbaf57fef8fbaeb45966b1feda3 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Fri, 10 Dec 2010 17:04:09 +0200 Subject: [PATCH 24/33] Better warning message if lock test fails Made archive.test a bit more safe mysql-test/r/archive.result: Added removal of files to make rerun of failed test work mysql-test/t/archive.test: Added removal of files to make rerun of failed test work mysys/thr_lock.c: Better warning message if lock test fails --- mysql-test/r/archive.result | 1 + mysql-test/t/archive.test | 5 +++++ mysys/thr_lock.c | 10 ++++------ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result index 5a731e6476c..ae79e237ade 100644 --- a/mysql-test/r/archive.result +++ b/mysql-test/r/archive.result @@ -12717,6 +12717,7 @@ COUNT(t1.a) 729 DROP TABLE t1; SET @@join_buffer_size= @save_join_buffer_size; +flush tables; SHOW CREATE TABLE t1; ERROR HY000: Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it! SELECT * FROM t1; diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index 7478c7dcdce..c966b51d861 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -1630,6 +1630,11 @@ SET @@join_buffer_size= @save_join_buffer_size; # BUG#47012 archive tables are not upgradeable, and server crashes on any access # let $MYSQLD_DATADIR= `SELECT @@datadir`; + +# Remove files to handle possible restart of test +flush tables; +remove_files_wildcard $MYSQLD_DATADIR/test t1.*; + copy_file std_data/bug47012.frm $MYSQLD_DATADIR/test/t1.frm; copy_file std_data/bug47012.ARZ $MYSQLD_DATADIR/test/t1.ARZ; copy_file std_data/bug47012.ARM $MYSQLD_DATADIR/test/t1.ARM; diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 341b2f0058e..60214c9af08 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -158,15 +158,13 @@ static int check_lock(struct st_lock_list *list, const char* lock_type, { THR_LOCK_DATA *data,**prev; uint count=0; - THR_LOCK_OWNER *UNINIT_VAR(first_owner); prev= &list->data; if (list->data) { - enum thr_lock_type last_lock_type=list->data->type; + enum thr_lock_type last_lock_type= list->data->type; + THR_LOCK_OWNER first_owner= list->data->owner; - if (same_owner && list->data) - first_owner= list->data->owner; for (data=list->data; data && count++ < MAX_LOCKS ; data=data->next) { if (data->type != last_lock_type) @@ -184,8 +182,8 @@ static int check_lock(struct st_lock_list *list, const char* lock_type, last_lock_type != TL_WRITE_CONCURRENT_INSERT) { fprintf(stderr, - "Warning: Found locks from different threads in %s: %s\n", - lock_type,where); + "Warning: Found locks from different threads in %s at '%s'. org_lock_type: %d last_lock_type: %d new_lock_type: %d\n", + lock_type, where, list->data->type, last_lock_type, data->type); return 1; } if (no_cond && data->cond) From bd2034dbee16bc90217d44df5059d837d60a6110 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Fri, 10 Dec 2010 17:15:18 +0200 Subject: [PATCH 25/33] Fix for Lbug:#686010 maria.optimize corrupts stack around alloca() call storage/maria/ma_check.c: Allocate also memory for nodflag and transid's storage/maria/ma_write.c: Allow nodflag and transid as part of key. (This has nothing to do with the bug report, but it's a safer check). storage/maria/maria_def.h: Define MARIA_MAX_POINTER_LENGTH (length of pointer to node) Added node pointer length to MARIA_INDEX_OVERHEAD_SIZE, as this is part of the key. (Safety fix) --- storage/maria/ma_check.c | 3 ++- storage/maria/ma_write.c | 6 ++---- storage/maria/maria_def.h | 4 +++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index fcf01385e97..1cb14567804 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -3133,7 +3133,8 @@ static int sort_one_index(HA_CHECK *param, MARIA_HA *info, key.keyinfo= keyinfo; if (!(buff= (uchar*) my_alloca((uint) keyinfo->block_length + - keyinfo->maxlength))) + keyinfo->maxlength + + MARIA_INDEX_OVERHEAD_SIZE))) { _ma_check_print_error(param,"Not enough memory for key block"); DBUG_RETURN(-1); diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c index 02eeec754ee..49f86fe291b 100644 --- a/storage/maria/ma_write.c +++ b/storage/maria/ma_write.c @@ -22,8 +22,6 @@ #include "ma_key_recover.h" #include "ma_blockrec.h" -#define MAX_POINTER_LENGTH 8 - /* Functions declared in this file */ static int w_search(MARIA_HA *info, uint32 comp_flag, @@ -802,7 +800,7 @@ int _ma_insert(register MARIA_HA *info, MARIA_KEY *key, #endif if (t_length > 0) { - if (t_length >= keyinfo->maxlength*2+MAX_POINTER_LENGTH) + if (t_length >= keyinfo->maxlength*2+MARIA_INDEX_OVERHEAD_SIZE) { my_errno=HA_ERR_CRASHED; DBUG_RETURN(-1); @@ -811,7 +809,7 @@ int _ma_insert(register MARIA_HA *info, MARIA_KEY *key, } else { - if (-t_length >= keyinfo->maxlength*2+MAX_POINTER_LENGTH) + if (-t_length >= keyinfo->maxlength*2+MARIA_INDEX_OVERHEAD_SIZE) { my_errno=HA_ERR_CRASHED; DBUG_RETURN(-1); diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index b998ac4f3a0..85696d04858 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -152,11 +152,13 @@ typedef struct st_maria_state_info #define MARIA_COLUMNDEF_SIZE (2*7+1+1+4) #define MARIA_BASE_INFO_SIZE (MY_UUID_SIZE + 5*8 + 6*4 + 11*2 + 6 + 5*2 + 1 + 16) #define MARIA_INDEX_BLOCK_MARGIN 16 /* Safety margin for .MYI tables */ +#define MARIA_MAX_POINTER_LENGTH 7 /* Node pointer */ /* Internal management bytes needed to store 2 transid/key on an index page */ #define MARIA_MAX_PACK_TRANSID_SIZE (TRANSID_SIZE+1) #define MARIA_TRANSID_PACK_OFFSET (256- TRANSID_SIZE - 1) #define MARIA_MIN_TRANSID_PACK_OFFSET (MARIA_TRANSID_PACK_OFFSET-TRANSID_SIZE) -#define MARIA_INDEX_OVERHEAD_SIZE (MARIA_MAX_PACK_TRANSID_SIZE * 2) +#define MARIA_INDEX_OVERHEAD_SIZE (MARIA_MAX_PACK_TRANSID_SIZE * 2 + \ + MARIA_MAX_POINTER_LENGTH) #define MARIA_DELETE_KEY_NR 255 /* keynr for deleted blocks */ /* From 597934eedfe72f8565d4b2d944a4b57846b72616 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 10 Dec 2010 20:58:28 -0800 Subject: [PATCH 26/33] Fixed compiler warnings. --- sql/opt_range.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index b0077187757..b16501aef2e 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -5075,7 +5075,8 @@ ha_rows records_in_index_intersect_extension(PARTIAL_INDEX_INTERSECTION_INFO *cu ha_rows table_cardinality= curr->common_info->table_cardinality; ha_rows records= curr->records; bitmap_copy(used_fields, curr->intersect_fields); - records= (double) records / table_cardinality * ext_index_scan->records; + records= (ha_rows) ((double) records / table_cardinality * + ext_index_scan->records); set_if_bigger(records, 1); for (uint i= 0 ; key_part < key_part_end; i++, key_part++) { @@ -5084,7 +5085,7 @@ ha_rows records_in_index_intersect_extension(PARTIAL_INDEX_INTERSECTION_INFO *cu ulong *rec_per_key= key_info->rec_per_key+i; ulong f1= rec_per_key[0] ? rec_per_key[0] : 1; ulong f2= i+1 < key_parts && rec_per_key[1] ? rec_per_key[1] : 1; - records= (double) records / f2 * f1; + records= (ha_rows) ((double) records / f2 * f1); } else { From 91f950b1c68089cee799adffdf0abb7ff639b579 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 10 Dec 2010 23:40:19 -0800 Subject: [PATCH 27/33] Fixed a compiler warning. --- sql/opt_range.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index b16501aef2e..627b9e5bd18 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -5168,9 +5168,9 @@ bool check_index_intersect_extension(PARTIAL_INDEX_INTERSECTION_INFO *curr, PARTIAL_INDEX_INTERSECTION_INFO *next) { ha_rows records; - ha_rows records2; ha_rows records_in_scans; double cost; + ha_rows records2= 0; ha_rows filtered_out_records= 0; ha_rows index_scan_records= ext_index_scan->records; COMMON_INDEX_INTERSECTION_INFO *common_info= curr->common_info; From ffb0cd6146662705491e1461a7727c9627f9bd15 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Mon, 13 Dec 2010 15:05:57 +0200 Subject: [PATCH 28/33] When compiling with valgrind, change my_alloca() to use my_malloc() - This allows us to detect missing my_afree() calls and also find overruns (when running with valgrind) to alloca() areas. - Added missing my_afree() calls - Fixed wrong call to my_afree() include/my_sys.h: When compiling with valgrind, change my_alloca() to use my_malloc() mysql-test/suite/innodb/t/innodb_bug57255.test: Speed up taste case (patch from Stewart Smith) mysql-test/suite/innodb_plugin/t/innodb_bug57255.test: Speed up taste case (patch from Stewart Smith) sql/ha_partition.cc: Removed casts from my_afree() sql/opt_range.cc: Add missing my_afree() calls. storage/maria/ma_rt_split.c: Fixed wrong parameter to my_afree() --- include/my_sys.h | 2 +- mysql-test/suite/innodb/t/innodb_bug57255.test | 2 ++ mysql-test/suite/innodb_plugin/t/innodb_bug57255.test | 2 ++ sql/ha_partition.cc | 4 ++-- sql/opt_range.cc | 2 ++ storage/maria/ma_rt_split.c | 3 +-- 6 files changed, 10 insertions(+), 5 deletions(-) diff --git a/include/my_sys.h b/include/my_sys.h index 309cb9c59b9..f5e38c5858e 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -197,7 +197,7 @@ extern void my_large_free(uchar * ptr, myf my_flags); #define my_large_free(A,B) my_free_lock((A),(B)) #endif /* HAVE_LARGE_PAGES */ -#ifdef HAVE_ALLOCA +#if defined(HAVE_ALLOCA) && !defined(HAVE_valgrind) #if defined(_AIX) && !defined(__GNUC__) && !defined(_AIX43) #pragma alloca #endif /* _AIX */ diff --git a/mysql-test/suite/innodb/t/innodb_bug57255.test b/mysql-test/suite/innodb/t/innodb_bug57255.test index 2b37a0a6092..0bf686578b2 100644 --- a/mysql-test/suite/innodb/t/innodb_bug57255.test +++ b/mysql-test/suite/innodb/t/innodb_bug57255.test @@ -12,6 +12,7 @@ create table C(id int not null auto_increment primary key, f1 int not null, fore insert into A values(1), (2); --disable_query_log +begin; let $i=257; while ($i) { @@ -24,6 +25,7 @@ while ($i) insert into C(f1) values(2); dec $i; } +commit; --enable_query_log # Following Deletes should not report error diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug57255.test b/mysql-test/suite/innodb_plugin/t/innodb_bug57255.test index 96184c355b6..e5056d3e23c 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb_bug57255.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug57255.test @@ -12,6 +12,7 @@ create table C(id int not null auto_increment primary key, f1 int not null, fore insert into A values(1), (2); --disable_query_log +begin; let $i=257; while ($i) { @@ -24,6 +25,7 @@ while ($i) insert into C(f1) values(2); dec $i; } +commit; --enable_query_log # Following Deletes should not report error diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index e2ad4b4462c..1e462130a32 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -2432,7 +2432,7 @@ bool ha_partition::get_from_handler_file(const char *name, MEM_ROOT *mem_root) for (i= 0; i < m_tot_parts; i++) m_engine_array[i]= ha_lock_engine(NULL, engine_array[i]); - my_afree((gptr) engine_array); + my_afree(engine_array); if (!m_file && create_handlers(mem_root)) { @@ -2442,7 +2442,7 @@ bool ha_partition::get_from_handler_file(const char *name, MEM_ROOT *mem_root) DBUG_RETURN(FALSE); err3: - my_afree((gptr) engine_array); + my_afree(engine_array); err2: my_free(file_buffer, MYF(0)); err1: diff --git a/sql/opt_range.cc b/sql/opt_range.cc index caacec164d2..5b4aa53bb91 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -11058,6 +11058,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_min_in_range() /* Compare the found key with max_key. */ int cmp_res= key_cmp(index_info->key_part, max_key, real_prefix_len + min_max_arg_len); + my_afree(max_key); /* The key is outside of the range if: the interval is open and the key is equal to the maximum boundry @@ -11183,6 +11184,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::next_max_in_range() /* Compare the found key with min_key. */ int cmp_res= key_cmp(index_info->key_part, min_key, real_prefix_len + min_max_arg_len); + my_afree(min_key); /* The key is outside of the range if: the interval is open and the key is equal to the minimum boundry diff --git a/storage/maria/ma_rt_split.c b/storage/maria/ma_rt_split.c index 856edc60490..6f32a60c073 100644 --- a/storage/maria/ma_rt_split.c +++ b/storage/maria/ma_rt_split.c @@ -544,8 +544,7 @@ int maria_rtree_split_page(const MARIA_KEY *key, MARIA_PAGE *page, } DBUG_PRINT("rtree", ("split new block: %lu", (ulong) *new_page_offs)); - my_afree(new_page); - + my_afree(new_page_buff); split_err: my_afree(coord_buf); DBUG_RETURN(err_code); From 0b20943e9d7e22332ccc14b30b49a78a780cc23d Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Mon, 13 Dec 2010 15:27:13 +0200 Subject: [PATCH 29/33] Fixed typo that caused compile failure in thr_lock.c mysys/thr_lock.c: Fixed typo that caused compile failure --- mysys/thr_lock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 60214c9af08..68a3caf6da7 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -163,7 +163,7 @@ static int check_lock(struct st_lock_list *list, const char* lock_type, if (list->data) { enum thr_lock_type last_lock_type= list->data->type; - THR_LOCK_OWNER first_owner= list->data->owner; + THR_LOCK_OWNER *first_owner= list->data->owner; for (data=list->data; data && count++ < MAX_LOCKS ; data=data->next) { From 970e67b5e3c459d0a6b8a0e4ce4a3bf602362fba Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 17 Dec 2010 08:33:36 +0100 Subject: [PATCH 30/33] MBug#691437: storage/sphinx/plug.in missing from source tarball. It was missing from EXTRA_DIST in Makefile.am. --- storage/sphinx/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/sphinx/Makefile.am b/storage/sphinx/Makefile.am index ce4324ae5cb..67d01d08484 100644 --- a/storage/sphinx/Makefile.am +++ b/storage/sphinx/Makefile.am @@ -49,6 +49,6 @@ libsphinx_la_CXXFLAGS = $(AM_CXXFLAGS) libsphinx_la_CFLAGS = $(AM_CFLAGS) libsphinx_la_SOURCES= ha_sphinx.cc -EXTRA_DIST = CMakeLists.txt +EXTRA_DIST = CMakeLists.txt plug.in # Don't update the files from bitkeeper %::SCCS/s.% From 65af63b038cb2ccc0503d6f67f6b70a8e9e438a0 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sun, 19 Dec 2010 00:44:39 -0800 Subject: [PATCH 31/33] Addressed the feedback from the review of Monty on the cumulative patch for mwl#21. --- include/my_tree.h | 9 + sql/filesort.cc | 82 +++--- sql/mysql_priv.h | 3 + sql/opt_range.cc | 724 ++++++++++++++++++++++++++-------------------- sql/opt_range.h | 128 ++++---- sql/sql_class.h | 3 +- 6 files changed, 532 insertions(+), 417 deletions(-) diff --git a/include/my_tree.h b/include/my_tree.h index ca207932c73..3aeef20e0ad 100644 --- a/include/my_tree.h +++ b/include/my_tree.h @@ -30,6 +30,15 @@ extern "C" { #define tree_set_pointer(element,ptr) *((uchar **) (element+1))=((uchar*) (ptr)) +/* + A tree with its flag set to TREE_ONLY_DUPS behaves differently on inserting + an element that is not in the tree: + the element is not added at all, but instead tree_insert() returns a special + address TREE_ELEMENT_UNIQUE as an indication that the function has not failed + due to lack of memory. +*/ + +#define TREE_ELEMENT_UNIQUE ((TREE_ELEMENT *) 1) #define TREE_NO_DUPS 1 #define TREE_ONLY_DUPS 2 diff --git a/sql/filesort.cc b/sql/filesort.cc index 42ce33af1ca..054f262852a 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -141,9 +141,6 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length, /* filesort cannot handle zero-length records. */ DBUG_ASSERT(param.sort_length); param.ref_length= table->file->ref_length; - param.min_dupl_count= 0; - param.addon_field= 0; - param.addon_length= 0; if (!(table->file->ha_table_flags() & HA_FAST_KEY_READ) && !table->fulltext_searched && !sort_positions) { @@ -1197,8 +1194,11 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, QUEUE queue; qsort2_cmp cmp; void *first_cmp_arg; - volatile THD::killed_state *killed= ¤t_thd->killed; + element_count dupl_count; + uchar *src; THD::killed_state not_killable; + uchar *unique_buff= param->unique_buff; + volatile THD::killed_state *killed= ¤t_thd->killed; DBUG_ENTER("merge_buffers"); status_var_increment(current_thd->status_var.filesort_merge_passes); @@ -1213,13 +1213,13 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, rec_length= param->rec_length; res_length= param->res_length; sort_length= param->sort_length; - element_count dupl_count; - uchar *src; uint dupl_count_ofs= rec_length-sizeof(element_count); uint min_dupl_count= param->min_dupl_count; - offset= rec_length- - (flag && min_dupl_count ? sizeof(dupl_count) : 0)-res_length; + bool check_dupl_count= flag && min_dupl_count; + offset= (rec_length- + (flag && min_dupl_count ? sizeof(dupl_count) : 0)-res_length); uint wr_len= flag ? res_length : rec_length; + uint wr_offset= flag ? offset : 0; maxcount= (ulong) (param->keys/((uint) (Tb-Fb) +1)); to_start_filepos= my_b_tell(to_file); strpos= sort_buffer; @@ -1228,7 +1228,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, /* The following will fire if there is not enough space in sort_buffer */ DBUG_ASSERT(maxcount!=0); - if (param->unique_buff) + if (unique_buff) { cmp= param->compare; first_cmp_arg= (void *) ¶m->cmp_context; @@ -1253,25 +1253,22 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, queue_insert(&queue, (uchar*) buffpek); } - if (param->unique_buff) + if (unique_buff) { /* Called by Unique::get() - Copy the first argument to param->unique_buff for unique removal. + Copy the first argument to unique_buff for unique removal. Store it also in 'to_file'. - - This is safe as we know that there is always more than one element - in each block to merge (This is guaranteed by the Unique:: algorithm */ buffpek= (BUFFPEK*) queue_top(&queue); - memcpy(param->unique_buff, buffpek->key, rec_length); + memcpy(unique_buff, buffpek->key, rec_length); if (min_dupl_count) - memcpy(&dupl_count, param->unique_buff+dupl_count_ofs, + memcpy(&dupl_count, unique_buff+dupl_count_ofs, sizeof(dupl_count)); buffpek->key+= rec_length; if (! --buffpek->mem_count) { - if (!(error= (int) read_to_buffer(from_file,buffpek, + if (!(error= (int) read_to_buffer(from_file, buffpek, rec_length))) { VOID(queue_remove(&queue,0)); @@ -1297,7 +1294,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, src= buffpek->key; if (cmp) // Remove duplicates { - if (!(*cmp)(first_cmp_arg, &(param->unique_buff), + if (!(*cmp)(first_cmp_arg, &unique_buff, (uchar**) &buffpek->key)) { if (min_dupl_count) @@ -1310,24 +1307,32 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, } if (min_dupl_count) { - memcpy(param->unique_buff+dupl_count_ofs, &dupl_count, + memcpy(unique_buff+dupl_count_ofs, &dupl_count, sizeof(dupl_count)); } - src= param->unique_buff; + src= unique_buff; } - if (!flag || !min_dupl_count || dupl_count >= min_dupl_count) + /* + Do not write into the output file if this is the final merge called + for a Unique object used for intersection and dupl_count is less + than min_dupl_count. + If the Unique object is used to intersect N sets of unique elements + then for any element: + dupl_count >= N <=> the element is occurred in each of these N sets. + */ + if (!check_dupl_count || dupl_count >= min_dupl_count) { - if (my_b_write(to_file, src+(flag ? offset : 0), wr_len)) + if (my_b_write(to_file, src+wr_offset, wr_len)) { error=1; goto err; /* purecov: inspected */ } } if (cmp) { - memcpy(param->unique_buff, (uchar*) buffpek->key, rec_length); + memcpy(unique_buff, (uchar*) buffpek->key, rec_length); if (min_dupl_count) - memcpy(&dupl_count, param->unique_buff+dupl_count_ofs, + memcpy(&dupl_count, unique_buff+dupl_count_ofs, sizeof(dupl_count)); } if (!--max_rows) @@ -1340,7 +1345,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, buffpek->key+= rec_length; if (! --buffpek->mem_count) { - if (!(error= (int) read_to_buffer(from_file,buffpek, + if (!(error= (int) read_to_buffer(from_file, buffpek, rec_length))) { VOID(queue_remove(&queue,0)); @@ -1363,7 +1368,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, */ if (cmp) { - if (!(*cmp)(first_cmp_arg, &(param->unique_buff), (uchar**) &buffpek->key)) + if (!(*cmp)(first_cmp_arg, &unique_buff, (uchar**) &buffpek->key)) { if (min_dupl_count) { @@ -1376,13 +1381,13 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, } if (min_dupl_count) - memcpy(param->unique_buff+dupl_count_ofs, &dupl_count, + memcpy(unique_buff+dupl_count_ofs, &dupl_count, sizeof(dupl_count)); - - if (!flag || !min_dupl_count || dupl_count >= min_dupl_count) + + if (!check_dupl_count || dupl_count >= min_dupl_count) { - src= param->unique_buff; - if (my_b_write(to_file, src+(flag ? offset : 0), wr_len)) + src= unique_buff; + if (my_b_write(to_file, src+wr_offset, wr_len)) { error=1; goto err; /* purecov: inspected */ } @@ -1404,7 +1409,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, max_rows-= buffpek->mem_count; if (flag == 0) { - if (my_b_write(to_file,(uchar*) buffpek->key, + if (my_b_write(to_file, (uchar*) buffpek->key, (rec_length*buffpek->mem_count))) { error= 1; goto err; /* purecov: inspected */ @@ -1418,11 +1423,12 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, src != end ; src+= rec_length) { - if (flag && min_dupl_count && - memcmp(&min_dupl_count, src+dupl_count_ofs, - sizeof(dupl_count_ofs))<0) - continue; - + if (check_dupl_count) + { + memcpy((uchar *) &dupl_count, src+dupl_count_ofs, sizeof(dupl_count)); + if (dupl_count < min_dupl_count) + continue; + } if (my_b_write(to_file, src, wr_len)) { error=1; goto err; @@ -1430,7 +1436,7 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file, } } } - while ((error=(int) read_to_buffer(from_file,buffpek, rec_length)) + while ((error=(int) read_to_buffer(from_file, buffpek, rec_length)) != -1 && error != 0); end: diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f8c36d87d52..f332aee0457 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -340,6 +340,9 @@ protected: */ #define TIME_FOR_COMPARE_ROWID (TIME_FOR_COMPARE*100) +/* cost1 is better that cost2 only if cost1 + COST_EPS < cost2 */ +#define COST_EPS 0.001 + /* For sequential disk seeks the cost formula is: DISK_SEEK_BASE_COST + DISK_SEEK_PROP_COST * #blocks_to_skip diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 627b9e5bd18..05c15f864db 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1735,11 +1735,11 @@ QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT() } -QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(THD *thd_param, - TABLE *table) +QUICK_INDEX_SORT_SELECT::QUICK_INDEX_SORT_SELECT(THD *thd_param, + TABLE *table) :unique(NULL), pk_quick_select(NULL), thd(thd_param) { - DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT"); + DBUG_ENTER("QUICK_INDEX_SORT_SELECT::QUICK_INDEX_SORT_SELECT"); index= MAX_KEY; head= table; bzero(&read_record, sizeof(read_record)); @@ -1747,38 +1747,37 @@ QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT(THD *thd_param, DBUG_VOID_RETURN; } -int QUICK_INDEX_MERGE_SELECT::init() +int QUICK_INDEX_SORT_SELECT::init() { - DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::init"); + DBUG_ENTER("QUICK_INDEX_SORT_SELECT::init"); DBUG_RETURN(0); } -int QUICK_INDEX_MERGE_SELECT::reset() +int QUICK_INDEX_SORT_SELECT::reset() { - DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::reset"); - DBUG_RETURN (read_keys_and_merge()); + DBUG_ENTER("QUICK_INDEX_SORT_SELECT::reset"); + DBUG_RETURN(read_keys_and_merge()); } bool -QUICK_INDEX_MERGE_SELECT::push_quick_back(QUICK_RANGE_SELECT *quick_sel_range) +QUICK_INDEX_SORT_SELECT::push_quick_back(QUICK_RANGE_SELECT *quick_sel_range) { - /* - Save quick_select that does scan on clustered primary key as it will be - processed separately. - */ + DBUG_ENTER("QUICK_INDEX_SORT_SELECT::push_quick_back"); if (head->file->primary_key_is_clustered() && quick_sel_range->index == head->s->primary_key) + { + /* A quick_select over a clustered primary key is handled specifically */ pk_quick_select= quick_sel_range; - else - return quick_selects.push_back(quick_sel_range); - return 0; + DBUG_RETURN(0); + } + DBUG_RETURN(quick_selects.push_back(quick_sel_range)); } -QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT() +QUICK_INDEX_SORT_SELECT::~QUICK_INDEX_SORT_SELECT() { List_iterator_fast quick_it(quick_selects); QUICK_RANGE_SELECT* quick; - DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT"); + DBUG_ENTER("QUICK_INDEX_SORT_SELECT::~QUICK_INDEX_SORT_SELECT"); delete unique; quick_it.rewind(); while ((quick= quick_it++)) @@ -1792,65 +1791,6 @@ QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT() DBUG_VOID_RETURN; } -QUICK_INDEX_INTERSECT_SELECT::QUICK_INDEX_INTERSECT_SELECT(THD *thd_param, - TABLE *table) - :unique(NULL), pk_quick_select(NULL), thd(thd_param) -{ - DBUG_ENTER("QUICK_INDEX_INTERSECT_SELECT::QUICK_INDEX_INTERSECT_SELECT"); - index= MAX_KEY; - head= table; - bzero(&read_record, sizeof(read_record)); - init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0); - DBUG_VOID_RETURN; -} - -int QUICK_INDEX_INTERSECT_SELECT::init() -{ - DBUG_ENTER("QUICK_INDEX_INTERSECT_SELECT::init"); - DBUG_RETURN(0); -} - -int QUICK_INDEX_INTERSECT_SELECT::reset() -{ - DBUG_ENTER("QUICK_INDEX_INTERSECT_SELECT::reset"); - DBUG_RETURN (read_keys_and_merge()); -} - -bool -QUICK_INDEX_INTERSECT_SELECT::push_quick_back(QUICK_RANGE_SELECT *quick_sel_range) -{ - /* - Save quick_select that does scan on clustered primary key as it will be - processed separately. - */ - if (head->file->primary_key_is_clustered() && - quick_sel_range->index == head->s->primary_key) - pk_quick_select= quick_sel_range; - else - return quick_selects.push_back(quick_sel_range); - return 0; -} - -QUICK_INDEX_INTERSECT_SELECT::~QUICK_INDEX_INTERSECT_SELECT() -{ - List_iterator_fast quick_it(quick_selects); - QUICK_RANGE_SELECT* quick; - DBUG_ENTER("QUICK_INDEX_INTERSECT_SELECT::~QUICK_INDEX_INTERSECT_SELECT"); - delete unique; - quick_it.rewind(); - while ((quick= quick_it++)) - quick->file= NULL; - quick_selects.delete_elements(); - delete pk_quick_select; - /* It's ok to call the next two even if they are already deinitialized */ - end_read_record(&read_record); - free_io_cache(head); - free_root(&alloc,MYF(0)); - DBUG_VOID_RETURN; -} - - - QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(THD *thd_param, TABLE *table, bool retrieve_full_rows, @@ -2655,6 +2595,8 @@ public: MEM_ROOT *parent_alloc); TRP_RANGE **range_scans; /* array of ptrs to plans of intersected scans */ TRP_RANGE **range_scans_end; /* end of the array */ + /* keys whose scans are to be filtered by cpk conditions */ + key_map filtered_scans; }; @@ -2738,6 +2680,9 @@ typedef struct st_index_scan_info KEY *key_info; uint used_key_parts; + /* Estimate of # records filtered out by intersection with cpk */ + ha_rows filtered_out; + /* Bitmap of fields used in index intersection */ MY_BITMAP used_fields; /* Fields used in the query and covered by ROR scan. */ @@ -3071,15 +3016,20 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, best_trp= rori_trp; } } - if (optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE) && + /* + Do not look for an index intersection plan if there is a covering + index. The scan by this covering index will be always cheaper than + any index intersection. + */ + if (param.table->covering_keys.is_clear_all() && + optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE) && optimizer_flag(thd, OPTIMIZER_SWITCH_INDEX_MERGE_SORT_INTERSECT)) { if ((intersect_trp= get_best_index_intersect(¶m, tree, best_read_time))) { best_trp= intersect_trp; - best_read_time= best_trp->read_cost; - + best_read_time= best_trp->read_cost; } } @@ -4756,7 +4706,7 @@ TABLE_READ_PLAN *merge_same_index_scans(PARAM *param, SEL_IMERGE *imerge, intersection plan. */ -typedef struct st_common_index_intersection_info +typedef struct st_common_index_intersect_info { PARAM *param; /* context info for range optimizations */ uint key_size; /* size of a ROWID element stored in Unique object */ @@ -4767,10 +4717,6 @@ typedef struct st_common_index_intersection_info INDEX_SCAN_INFO *cpk_scan; /* clustered primary key used in intersection */ bool in_memory; /* unique object for intersection is completely in memory */ - /* estimate of the number of records filtered out from the first scan by - ranges for the clustered primary key scan (cpk_scan) */ - ha_rows filtered_out_records; - double filter_cost; /* cost of checking the the cpk_scan rabhe conditions */ INDEX_SCAN_INFO **search_scans; /* scans possibly included in intersect */ uint n_search_scans; /* number of elements in search_scans */ @@ -4781,10 +4727,12 @@ typedef struct st_common_index_intersection_info ha_rows best_records; uint best_length; /* number of indexes in the current best intersection */ INDEX_SCAN_INFO **best_intersect; /* the current best index intersection */ + /* scans from the best intersect to be filtrered by cpk conditions */ + key_map filtered_scans; uint *buff_elems; /* buffer to calculate cost of index intersection */ -} COMMON_INDEX_INTERSECTION_INFO; +} COMMON_INDEX_INTERSECT_INFO; /* @@ -4793,25 +4741,28 @@ typedef struct st_common_index_intersection_info check_index_intersect_extension. */ -typedef struct st_partial_index_intersection_info +typedef struct st_partial_index_intersect_info { - COMMON_INDEX_INTERSECTION_INFO *common_info; /* shared by index intersects */ + COMMON_INDEX_INTERSECT_INFO *common_info; /* shared by index intersects */ uint length; /* number of index scans in the partial intersection */ ha_rows records; /* estimate of the number of records in intersection */ double cost; /* cost of the partial index intersection */ - /* estimate of total number of records in all index scans of intersection */ - ha_rows records_in_scans; + /* estimate of total number of records of all scans of the partial index + intersect sent to the Unique object used for the intersection */ + ha_rows records_sent_to_unique; /* total cost of the scans of indexes from the partial index intersection */ double index_read_cost; - bool with_cpk_filter; /* cpk filter is to be used for the first scan */ + bool use_cpk_filter; /* cpk filter is to be used for this scan */ bool in_memory; /* uses unique object in memory */ double in_memory_cost; /* cost of using unique object in memory */ + + key_map filtered_scans; /* scans to be filtered by cpk conditions */ MY_BITMAP *intersect_fields; /* bitmap of fields used in intersection */ -} PARTIAL_INDEX_INTERSECTION_INFO; +} PARTIAL_INDEX_INTERSECT_INFO; /* Check whether two indexes have the same first n components */ @@ -4856,6 +4807,20 @@ int cmp_intersect_index_scan(INDEX_SCAN_INFO **a, INDEX_SCAN_INFO **b) } +static inline +void set_field_bitmap_for_index_prefix(MY_BITMAP *field_bitmap, + KEY_PART_INFO *key_part, + uint used_key_parts) +{ + bitmap_clear_all(field_bitmap); + for (KEY_PART_INFO *key_part_end= key_part+used_key_parts; + key_part < key_part_end; key_part++) + { + bitmap_set_bit(field_bitmap, key_part->fieldnr-1); + } +} + + /* Round up table cardinality read from statistics provided by engine. This function should go away when mysql test will allow to handle @@ -4878,6 +4843,10 @@ ha_rows get_table_cardinality_for_index_intersect(TABLE *table) } +static +ha_rows records_in_index_intersect_extension(PARTIAL_INDEX_INTERSECT_INFO *curr, + INDEX_SCAN_INFO *ext_index_scan); + /* Prepare to search for the best index intersection @@ -4889,7 +4858,7 @@ ha_rows get_table_cardinality_for_index_intersect(TABLE *table) init OUT info for an initial pseudo step of the intersection plans cutoff_cost cut off cost of the interesting index intersection - NOTES + DESCRIPTION The function initializes all fields of the structure 'common' to be used when searching for the best intersection plan. It also allocates memory to store the most cheap index intersection. @@ -4902,11 +4871,12 @@ ha_rows get_table_cardinality_for_index_intersect(TABLE *table) static bool prepare_search_best_index_intersect(PARAM *param, SEL_TREE *tree, - COMMON_INDEX_INTERSECTION_INFO *common, - PARTIAL_INDEX_INTERSECTION_INFO *init, + COMMON_INDEX_INTERSECT_INFO *common, + PARTIAL_INDEX_INTERSECT_INFO *init, double cutoff_cost) { uint i; + uint n_search_scans; double cost; INDEX_SCAN_INFO **index_scan; INDEX_SCAN_INFO **scan_ptr; @@ -4917,9 +4887,9 @@ bool prepare_search_best_index_intersect(PARAM *param, if (!n_index_scans) return 1; - bzero(init, sizeof(PARTIAL_INDEX_INTERSECTION_INFO)); + bzero(init, sizeof(*init)); init->common_info= common; - init->cost= cutoff_cost+2*0.01; + init->cost= cutoff_cost; common->param= param; common->key_size= table->file->ref_length; @@ -4927,20 +4897,24 @@ bool prepare_search_best_index_intersect(PARAM *param, common->max_memory_size= param->thd->variables.sortbuff_size; common->cutoff_cost= cutoff_cost; common->cpk_scan= NULL; - common->filtered_out_records= 0; common->table_cardinality= get_table_cardinality_for_index_intersect(table); if (n_index_scans <= 1) return TRUE; - for (i=0, index_scan= tree->index_scans; i < n_index_scans; i++, index_scan++) - { - if ((*index_scan)->keynr == table->s->primary_key && - table->file->primary_key_is_clustered()) - { - common->cpk_scan= cpk_scan= *index_scan; - break; + if (table->file->primary_key_is_clustered()) + { + INDEX_SCAN_INFO **index_scan_end; + index_scan= tree->index_scans; + index_scan_end= index_scan+n_index_scans; + for ( ; index_scan < index_scan_end; index_scan++) + { + if ((*index_scan)->keynr == table->s->primary_key) + { + common->cpk_scan= cpk_scan= *index_scan; + break; + } } } @@ -4973,14 +4947,21 @@ bool prepare_search_best_index_intersect(PARAM *param, for (scan_ptr= selected_index_scans; *scan_ptr ; scan_ptr++) { + /* + When we have range conditions for two different indexes with the same + beginning it does not make sense to consider both of them for index + intersection if the range conditions are covered by common initial + components of the indexes. Actually in this case the indexes are + guaranteed to have the same range conditions. + */ if ((*scan_ptr)->used_key_parts == used_key_parts && same_index_prefix((*scan_ptr)->key_info, key_info, used_key_parts)) break; } if (!*scan_ptr || cost < (*scan_ptr)->index_read_cost) { - (*index_scan)->index_read_cost= cost; *scan_ptr= *index_scan; + (*scan_ptr)->index_read_cost= cost; } } @@ -4992,15 +4973,16 @@ bool prepare_search_best_index_intersect(PARAM *param, return TRUE; records_in_scans+= (*scan_ptr)->records; } + n_search_scans= i; if (cpk_scan && create_fields_bitmap(param, &cpk_scan->used_fields)) return TRUE; - if (!(common->n_search_scans= i)) + if (!(common->n_search_scans= n_search_scans)) return TRUE; common->best_uses_cpk= FALSE; - common->best_cost= cutoff_cost + 0.01; + common->best_cost= cutoff_cost + COST_EPS; common->best_length= 0; if (!(common->best_intersect= @@ -5009,7 +4991,7 @@ bool prepare_search_best_index_intersect(PARAM *param, (i + test(cpk_scan != NULL))))) return TRUE; - uint calc_cost_buff_size= + size_t calc_cost_buff_size= Unique::get_cost_calc_buff_size(records_in_scans, common->key_size, common->max_memory_size); @@ -5017,25 +4999,167 @@ bool prepare_search_best_index_intersect(PARAM *param, calc_cost_buff_size))) return TRUE; - my_qsort(selected_index_scans, i, sizeof(INDEX_SCAN_INFO *), + my_qsort(selected_index_scans, n_search_scans, sizeof(INDEX_SCAN_INFO *), (qsort_cmp) cmp_intersect_index_scan); + if (cpk_scan) + { + PARTIAL_INDEX_INTERSECT_INFO curr; + set_field_bitmap_for_index_prefix(&cpk_scan->used_fields, + cpk_scan->key_info->key_part, + cpk_scan->used_key_parts); + curr.common_info= common; + curr.intersect_fields= &cpk_scan->used_fields; + curr.records= cpk_scan->records; + curr.length= 1; + for (scan_ptr=selected_index_scans, i= 0; *scan_ptr; scan_ptr++, i++) + { + ha_rows scan_records= (*scan_ptr)->records; + ha_rows records= records_in_index_intersect_extension(&curr, *scan_ptr); + (*scan_ptr)->filtered_out= records >= scan_records ? + 0 : scan_records-records; + } + } + else + { + for (scan_ptr=selected_index_scans, i= 0; *scan_ptr; scan_ptr++, i++) + (*scan_ptr)->filtered_out= 0; + } + return FALSE; } -static inline -void set_field_bitmap_for_index_prefix(MY_BITMAP *field_bitmap, - KEY_PART_INFO *key_part, - uint used_key_parts) -{ - bitmap_clear_all(field_bitmap); - for (KEY_PART_INFO *key_part_end= key_part+used_key_parts; - key_part < key_part_end; key_part++) - { - bitmap_set_bit(field_bitmap, key_part->fieldnr-1); - } -} +/* + On Estimation of the Number of Records in an Index Intersection + =============================================================== + + Consider query Q over table t. Let C be the WHERE condition of this query, + and, idx1(a1_1,...,a1_k1) and idx2(a2_1,...,a2_k2) be some indexes defined + on table t. + Let rt1 and rt2 be the range trees extracted by the range optimizer from C + for idx1 and idx2 respectively. + Let #t be the estimate of the number of records in table t provided for the + optimizer. + Let #r1 and #r2 be the estimates of the number of records in the range trees + rt1 and rt2, respectively, obtained by the range optimizer. + + We need to get an estimate for the number of records in the index + intersection of rt1 and rt2. In other words, we need to estimate the + cardinality of the set of records that are in both trees. Let's designate + this number by #r. + + If we do not make any assumptions then we can only state that + #r<=min(#r1,#r2). + With this estimate we can't say that the index intersection scan will be + cheaper than the cheapest index scan. + + Let Rt1 and Rt2 be AND/OR conditions representing rt and rt2 respectively. + The probability that a record belongs to rt1 is sel(Rt1)=#r1/#t. + The probability that a record belongs to rt2 is sel(Rt2)=#r2/#t. + + If we assume that the values in columns of idx1 and idx2 are independent + then #r/#t=sel(Rt1&Rt2)=sel(Rt1)*sel(Rt2)=(#r1/#t)*(#r2/#t). + So in this case we have: #r=#r1*#r2/#t. + + The above assumption of independence of the columns in idx1 and idx2 means + that: + - all columns are different + - values from one column do not correlate with values from any other column. + + We can't help with the case when column correlate with each other. + Yet, if they are assumed to be uncorrelated the value of #r theoretically can + be evaluated . Unfortunately this evaluation, in general, is rather complex. + + Let's consider two indexes idx1:(dept, manager), idx2:(dept, building) + over table 'employee' and two range conditions over these indexes: + Rt1: dept=10 AND manager LIKE 'S%' + Rt2: dept=10 AND building LIKE 'L%'. + We can state that: + sel(Rt1&Rt2)=sel(dept=10)*sel(manager LIKE 'S%')*sel(building LIKE 'L%') + =sel(Rt1)*sel(Rt2)/sel(dept=10). + sel(Rt1/2_0:dept=10) can be estimated if we know the cardinality #r1_0 of + the range for sub-index idx1_0 (dept) of the index idx1 or the cardinality + #rt2_0 of the same range for sub-index idx2_0(dept) of the index idx2. + The current code does not make an estimate either for #rt1_0, or for #rt2_0, + but it can be adjusted to provide those numbers. + Alternatively, min(rec_per_key) for (dept) could be used to get an upper + bound for the value of sel(Rt1&Rt2). Yet this statistics is not provided + now. + + Let's consider two other indexes idx1:(dept, last_name), + idx2:(first_name, last_name) and two range conditions over these indexes: + Rt1: dept=5 AND last_name='Sm%' + Rt2: first_name='Robert' AND last_name='Sm%'. + + sel(Rt1&Rt2)=sel(dept=5)*sel(last_name='Sm5')*sel(first_name='Robert') + =sel(Rt2)*sel(dept=5) + Here max(rec_per_key) for (dept) could be used to get an upper bound for + the value of sel(Rt1&Rt2). + + When the intersected indexes have different major columns, but some + minor column are common the picture may be more complicated. + + Let's consider the following range conditions for the same indexes as in + the previous example: + Rt1: (Rt11: dept=5 AND last_name='So%') + OR + (Rt12: dept=7 AND last_name='Saw%') + Rt2: (Rt21: first_name='Robert' AND last_name='Saw%') + OR + (Rt22: first_name='Bob' AND last_name='So%') + Here we have: + sel(Rt1&Rt2)= sel(Rt11)*sel(Rt21)+sel(Rt22)*sel(dept=5) + + sel(Rt21)*sel(dept=7)+sel(Rt12)*sel(Rt22) + Now consider the range condition: + Rt1_0: (dept=5 OR dept=7) + For this condition we can state that: + sel(Rt1_0&Rt2)=(sel(dept=5)+sel(dept=7))*(sel(Rt21)+sel(Rt22))= + sel(dept=5)*sel(Rt21)+sel(dept=7)*sel(Rt21)+ + sel(dept=5)*sel(Rt22)+sel(dept=7)*sel(Rt22)= + sel(dept=5)*sel(Rt21)+sel(Rt21)*sel(dept=7)+ + sel(Rt22)*sel(dept=5)+sel(dept=7)*sel(Rt22) > + sel(Rt11)*sel(Rt21)+sel(Rt22)*sel(dept=5)+ + sel(Rt21)*sel(dept=7)+sel(Rt12)*sel(Rt22) > + sel(Rt1 & Rt2) + + We've just demonstrated for an example what is intuitively almost obvious + in general. We can remove the ending parts fromrange trees getting less + selective range conditions for sub-indexes. + So if not a most major component with the number k of an index idx is + encountered in the index with which we intersect we can use the sub-index + idx_k-1 that includes the components of idx up to the i-th component and + the range tree for idx_k-1 to make an upper bound estimate for the number + of records in the index intersection. + The range tree for idx_k-1 we use here is the subtree of the original range + tree for idx that contains only parts from the first k-1 components. + + As it was mentioned above the range optimizer currently does not provide + an estimate for the number of records in the ranges for sub-indexes. + However, some reasonable upper bound estimate can be obtained. + + Let's consider the following range tree: + Rt: (first_name='Robert' AND last_name='Saw%') + OR + (first_name='Bob' AND last_name='So%') + Let #r be the number of records in Rt. Let f_1 be the fan-out of column + last_name: + f_1 = rec_per_key[first_name]/rec_per_key[last_name]. + The the number of records in the range tree: + Rt_0: (first_name='Robert' OR first_name='Bob') + for the sub-index (first_name) is not greater than max(#r*f_1, #t). + Strictly speaking, we can state only that it's not greater than + max(#r*max_f_1, #t), where + max_f_1= max_rec_per_key[first_name]/min_rec_per_key[last_name]. + Yet, if #r/#t is big enough (and this is the case of an index intersection, + because using this index range with a single index scan is cheaper than + the cost of the intersection when #r/#t is small) then almost safely we + can use here f_1 instead of max_f_1. + + The above considerations can be used in future development. Now, they are + used partly in the function that provides a rough upper bound estimate for + the number of records in an index intersection that follow below. +*/ /* Estimate the number of records selected by an extension a partial intersection @@ -5045,101 +5169,94 @@ void set_field_bitmap_for_index_prefix(MY_BITMAP *field_bitmap, curr partial intersection plan to be extended ext_index_scan the evaluated extension of this partial plan - NOTES - The function figures out how many records can be expected if the - index scans from curr is intersected with ext_index_scan + DESCRIPTION + The function provides an estimate for the number of records in the + intersection of the partial index intersection curr with the index + ext_index_scan. If all intersected indexes does not have common columns + then the function returns an exact estimate (assuming there are no + correlations between values in the columns). If the intersected indexes + have common columns the function returns an upper bound for the number + of records in the intersection provided that the intersection of curr + with ext_index_scan can is expected to have less records than the expected + number of records in the partial intersection curr. In this case the + function also assigns the bitmap of the columns in the extended + intersection to ext_index_scan->used_fields. + If the function cannot expect that the number of records in the extended + intersection is less that the expected number of records #r in curr then + the function returns a number bigger than #r. + NOTES + See the comment before the desription of the function that explains the + reasoning used by this function. + RETURN The expected number of rows in the extended index intersection */ static -ha_rows records_in_index_intersect_extension(PARTIAL_INDEX_INTERSECTION_INFO *curr, +ha_rows records_in_index_intersect_extension(PARTIAL_INDEX_INTERSECT_INFO *curr, INDEX_SCAN_INFO *ext_index_scan) { KEY *key_info= ext_index_scan->key_info; KEY_PART_INFO* key_part= key_info->key_part; - KEY_PART_INFO* key_part_end= key_part+ext_index_scan->used_key_parts; - uint key_parts= key_info->key_parts; + uint used_key_parts= ext_index_scan->used_key_parts; MY_BITMAP *used_fields= &ext_index_scan->used_fields; if (!curr->length) { - set_field_bitmap_for_index_prefix(used_fields, key_part, - ext_index_scan->used_key_parts); + /* + If this the first index in the intersection just mark the + fields in the used_fields bitmap and return the expected + number of records in the range scan for the index provided + by the range optimizer. + */ + set_field_bitmap_for_index_prefix(used_fields, key_part, used_key_parts); return ext_index_scan->records; } - else + + uint i; + bool better_selectivity= FALSE; + ha_rows records= curr->records; + MY_BITMAP *curr_intersect_fields= curr->intersect_fields; + for (i= 0; i < used_key_parts; i++, key_part++) + { + if (bitmap_is_set(curr_intersect_fields, key_part->fieldnr-1)) + break; + } + if (i) { - bool better_selectivity= FALSE; ha_rows table_cardinality= curr->common_info->table_cardinality; - ha_rows records= curr->records; - bitmap_copy(used_fields, curr->intersect_fields); - records= (ha_rows) ((double) records / table_cardinality * - ext_index_scan->records); - set_if_bigger(records, 1); - for (uint i= 0 ; key_part < key_part_end; i++, key_part++) + ha_rows ext_records= ext_index_scan->records; + if (i < used_key_parts) { - if (bitmap_is_set(used_fields, key_part->fieldnr-1)) - { - ulong *rec_per_key= key_info->rec_per_key+i; - ulong f1= rec_per_key[0] ? rec_per_key[0] : 1; - ulong f2= i+1 < key_parts && rec_per_key[1] ? rec_per_key[1] : 1; - records= (ha_rows) ((double) records / f2 * f1); - } - else - { - better_selectivity= TRUE; - bitmap_set_bit(used_fields, key_part->fieldnr-1); - } + ulong *rec_per_key= key_info->rec_per_key+i-1; + ulong f1= rec_per_key[0] ? rec_per_key[0] : 1; + ulong f2= rec_per_key[1] ? rec_per_key[1] : 1; + ext_records= (ha_rows) ((double) ext_records / f2 * f1); } - return !better_selectivity ? curr->records+1 : - !records ? 1 : records; - } + if (ext_records < table_cardinality) + { + better_selectivity= TRUE; + records= (ha_rows) ((double) records / table_cardinality * + ext_records); + bitmap_copy(used_fields, curr_intersect_fields); + key_part= key_info->key_part; + for (uint j= 0; j < used_key_parts; j++, key_part++) + bitmap_set_bit(used_fields, key_part->fieldnr-1); + } + } + return !better_selectivity ? records+1 : + !records ? 1 : records; } static inline -double get_unique_intersect_cost(COMMON_INDEX_INTERSECTION_INFO *common, - uint length, ha_rows records_in_scans, - ha_rows filtered_out_records, - ha_rows last_index_records, - bool *in_memory, - double *in_memory_cost) -{ - double cost; - if (length > 1 && *in_memory) - { - ha_rows records_in_first_scan= common->search_scans[0]->records; - ha_rows elems_in_tree= records_in_first_scan-filtered_out_records; - *in_memory_cost+= Unique::get_search_cost(elems_in_tree, - common->compare_factor) * - last_index_records; - cost= *in_memory_cost; - } - else - { - ha_rows records_to_intersect= records_in_scans-filtered_out_records; - cost= Unique::get_use_cost(common->buff_elems, - records_to_intersect, - common->key_size, - common->max_memory_size, - common->compare_factor, - TRUE, in_memory); - if (*in_memory) - *in_memory_cost= cost; - } - return cost; -} - - -static inline -double get_cpk_filter_cost(INDEX_SCAN_INFO *index_scan, +double get_cpk_filter_cost(ha_rows filtered_records, INDEX_SCAN_INFO *cpk_scan, double compare_factor) { return log((double) (cpk_scan->range_count+1)) / (compare_factor * M_LN2) * - index_scan->records; + filtered_records; } @@ -5152,104 +5269,112 @@ double get_cpk_filter_cost(INDEX_SCAN_INFO *index_scan, ext_index_scan a possible extension of this plan to be checked next OUT the structure to be filled for the extended plan - NOTES + DESCRIPTION The function checks whether it makes sense to extend the index intersection plan adding the index ext_index_scan, and, if this - the case, the function fills in the structure fir the extended plan. + the case, the function fills in the structure for the extended plan. RETURN - TRUE if the given plan makes to extend + TRUE if it makes sense to extend the given plan FALSE otherwise */ static -bool check_index_intersect_extension(PARTIAL_INDEX_INTERSECTION_INFO *curr, +bool check_index_intersect_extension(PARTIAL_INDEX_INTERSECT_INFO *curr, INDEX_SCAN_INFO *ext_index_scan, - PARTIAL_INDEX_INTERSECTION_INFO *next) + PARTIAL_INDEX_INTERSECT_INFO *next) { ha_rows records; - ha_rows records_in_scans; + ha_rows records_sent_to_unique; double cost; - ha_rows records2= 0; - ha_rows filtered_out_records= 0; - ha_rows index_scan_records= ext_index_scan->records; - COMMON_INDEX_INTERSECTION_INFO *common_info= curr->common_info; - INDEX_SCAN_INFO *cpk_scan= common_info->cpk_scan; + ha_rows ext_index_scan_records= ext_index_scan->records; + ha_rows records_filtered_out_by_cpk= ext_index_scan->filtered_out; + COMMON_INDEX_INTERSECT_INFO *common_info= curr->common_info; double cutoff_cost= common_info->cutoff_cost; - uint compare_factor= common_info->compare_factor; uint idx= curr->length; - bool with_cpk_filter= curr->with_cpk_filter; - - if (with_cpk_filter) - filtered_out_records= common_info->filtered_out_records; - next->index_read_cost= curr->index_read_cost+ext_index_scan->index_read_cost; if (next->index_read_cost > cutoff_cost) return FALSE; - records_in_scans= curr->records_in_scans + index_scan_records; if ((next->in_memory= curr->in_memory)) next->in_memory_cost= curr->in_memory_cost; + next->intersect_fields= &ext_index_scan->used_fields; + next->filtered_scans= curr->filtered_scans; + + records_sent_to_unique= curr->records_sent_to_unique; + + next->use_cpk_filter= FALSE; + + /* Calculate the cost of using a Unique object for index intersection */ + if (idx && next->in_memory) + { + /* + All rowids received from the first scan are expected in one unique tree + */ + ha_rows elems_in_tree= common_info->search_scans[0]->records- + common_info->search_scans[0]->filtered_out ; + next->in_memory_cost+= Unique::get_search_cost(elems_in_tree, + common_info->compare_factor)* + ext_index_scan_records; + cost= next->in_memory_cost; + } + else + { + uint *buff_elems= common_info->buff_elems; + uint key_size= common_info->key_size; + uint compare_factor= common_info->compare_factor; + ulonglong max_memory_size= common_info->max_memory_size; + + records_sent_to_unique+= ext_index_scan_records; + cost= Unique::get_use_cost(buff_elems, records_sent_to_unique, key_size, + max_memory_size, compare_factor, TRUE, + &next->in_memory); + if (records_filtered_out_by_cpk) + { + /* Check whether using cpk filter for this scan is beneficial */ + + double cost2; + bool in_memory2; + ha_rows records2= records_sent_to_unique-records_filtered_out_by_cpk; + cost2= Unique::get_use_cost(buff_elems, records2, key_size, + max_memory_size, compare_factor, TRUE, + &in_memory2); + cost2+= get_cpk_filter_cost(ext_index_scan_records, common_info->cpk_scan, + compare_factor); + if (cost > cost2 + COST_EPS) + { + cost= cost2; + next->in_memory= in_memory2; + next->use_cpk_filter= TRUE; + records_sent_to_unique= records2; + } + + } + if (next->in_memory) + next->in_memory_cost= cost; + } + + if (next->use_cpk_filter) + { + next->filtered_scans.set_bit(ext_index_scan->keynr); + bitmap_union(&ext_index_scan->used_fields, + &common_info->cpk_scan->used_fields); + } + next->records_sent_to_unique= records_sent_to_unique; + records= records_in_index_intersect_extension(curr, ext_index_scan); if (idx && records > curr->records) return FALSE; - + if (next->use_cpk_filter && curr->filtered_scans.is_clear_all()) + records-= records_filtered_out_by_cpk; next->records= records; - next->intersect_fields= &ext_index_scan->used_fields; - cost= get_unique_intersect_cost(common_info, idx+1, records_in_scans, - filtered_out_records, index_scan_records, - &next->in_memory, &next->in_memory_cost); - - if (idx == 0 && cpk_scan) - { - next->length= 1; - records2= records_in_index_intersect_extension(next, cpk_scan); - next->length= 0; - if (records2 < records) - filtered_out_records= records-records2; - - common_info->filter_cost= get_cpk_filter_cost(ext_index_scan, cpk_scan, - compare_factor); - common_info->filtered_out_records= filtered_out_records; - } - - next->records_in_scans= records_in_scans; - next->with_cpk_filter= with_cpk_filter; - - if (!with_cpk_filter && common_info->filtered_out_records) - { - double cost2; - bool in_memory_save= next->in_memory; - if (idx) - { - next->length= curr->length+1; - records2= records_in_index_intersect_extension(next, cpk_scan); - next->length= curr->length; - } - cost2= get_unique_intersect_cost(common_info, idx+1, records_in_scans, - filtered_out_records, index_scan_records, - &next->in_memory, &next->in_memory_cost); - cost2+= common_info->filter_cost; - if (cost2 < cost) - { - cost= cost2; - records= records2; - next->with_cpk_filter= TRUE; - *next->intersect_fields= cpk_scan->used_fields; - } - else - next->in_memory= in_memory_save; - } - cost+= next->index_read_cost; if (cost >= cutoff_cost) return FALSE; - next->records= records; - - cost+= get_sweep_read_cost(common_info->param, records); + cost+= get_sweep_read_cost(common_info->param, records); next->cost= cost; next->length= curr->length+1; @@ -5265,28 +5390,29 @@ bool check_index_intersect_extension(PARTIAL_INDEX_INTERSECTION_INFO *curr, find_index_intersect_best_extension() curr partial intersection to evaluate all possible extension for - NOTES + DESCRIPTION The function tries to extend the partial plan curr in all possible ways to look for a cheapest index intersection whose cost less than the cut off value set in curr->common_info.cutoff_cost. */ static -void find_index_intersect_best_extension(PARTIAL_INDEX_INTERSECTION_INFO *curr) +void find_index_intersect_best_extension(PARTIAL_INDEX_INTERSECT_INFO *curr) { - PARTIAL_INDEX_INTERSECTION_INFO next; - COMMON_INDEX_INTERSECTION_INFO *common_info= curr->common_info; + PARTIAL_INDEX_INTERSECT_INFO next; + COMMON_INDEX_INTERSECT_INFO *common_info= curr->common_info; INDEX_SCAN_INFO **index_scans= common_info->search_scans; uint idx= curr->length; INDEX_SCAN_INFO **rem_first_index_scan_ptr= &index_scans[idx]; double cost= curr->cost; - if (cost < common_info->best_cost) + if (cost + COST_EPS < common_info->best_cost) { common_info->best_cost= cost; common_info->best_length= curr->length; common_info->best_records= curr->records; - common_info->best_uses_cpk= curr->with_cpk_filter; + common_info->filtered_scans= curr->filtered_scans; + common_info->best_uses_cpk= !curr->filtered_scans.is_clear_all(); uint sz= sizeof(INDEX_SCAN_INFO *) * curr->length; memcpy(common_info->best_intersect, common_info->search_scans, sz); common_info->cutoff_cost= cost; @@ -5320,7 +5446,7 @@ void find_index_intersect_best_extension(PARTIAL_INDEX_INTERSECTION_INFO *curr) tree tree of ranges for indexes than can be intersected read_time cut off value for the evaluated plans - NOTES + DESCRIPTION The function looks for the cheapest index intersection of the range scans to access a table. The info about the ranges for all indexes is provided by the range optimizer and is passed through the @@ -5343,8 +5469,8 @@ TRP_INDEX_INTERSECT *get_best_index_intersect(PARAM *param, SEL_TREE *tree, TRP_RANGE **cur_range; TRP_RANGE **range_scans; INDEX_SCAN_INFO *index_scan; - COMMON_INDEX_INTERSECTION_INFO common; - PARTIAL_INDEX_INTERSECTION_INFO init; + COMMON_INDEX_INTERSECT_INFO common; + PARTIAL_INDEX_INTERSECT_INFO init; TRP_INDEX_INTERSECT *intersect_trp= NULL; TABLE *table= param->table; @@ -5383,7 +5509,7 @@ TRP_INDEX_INTERSECT *get_best_index_intersect(PARAM *param, SEL_TREE *tree, { TRP_RANGE *trp= *cur_range; trp->read_cost= index_scan->index_read_cost; - trp->records= index_scan->records; + trp->records= index_scan->records; trp->is_ror= FALSE; table->intersect_keys.set_bit(index_scan->keynr); cur_range++; @@ -5415,6 +5541,7 @@ TRP_INDEX_INTERSECT *get_best_index_intersect(PARAM *param, SEL_TREE *tree, intersect_trp->records= common.best_records; intersect_trp->range_scans= range_scans; intersect_trp->range_scans_end= cur_range; + intersect_trp->filtered_scans= common.filtered_scans; } DBUG_RETURN(intersect_trp); } @@ -6426,6 +6553,7 @@ QUICK_SELECT_I *TRP_INDEX_INTERSECT::make_quick(PARAM *param, quick_intersect->records= records; quick_intersect->read_time= read_cost; + quick_intersect->filtered_scans= filtered_scans; for (TRP_RANGE **range_scan= range_scans; range_scan != range_scans_end; range_scan++) { @@ -9827,19 +9955,7 @@ bool QUICK_SELECT_I::is_keys_used(const MY_BITMAP *fields) return is_key_used(head, index, fields); } -bool QUICK_INDEX_MERGE_SELECT::is_keys_used(const MY_BITMAP *fields) -{ - QUICK_RANGE_SELECT *quick; - List_iterator_fast it(quick_selects); - while ((quick= it++)) - { - if (is_key_used(head, quick->index, fields)) - return 1; - } - return 0; -} - -bool QUICK_INDEX_INTERSECT_SELECT::is_keys_used(const MY_BITMAP *fields) +bool QUICK_INDEX_SORT_SELECT::is_keys_used(const MY_BITMAP *fields) { QUICK_RANGE_SELECT *quick; List_iterator_fast it(quick_selects); @@ -10002,6 +10118,7 @@ int read_keys_and_merge_scans(THD *thd, QUICK_RANGE_SELECT *pk_quick_select, READ_RECORD *read_record, bool intersection, + key_map *filtered_scans, Unique **unique_ptr) { List_iterator_fast cur_quick_it(quick_selects); @@ -10009,6 +10126,8 @@ int read_keys_and_merge_scans(THD *thd, int result; Unique *unique= *unique_ptr; handler *file= head->file; + bool with_cpk_filter= pk_quick_select != NULL; + DBUG_ENTER("read_keys_and_merge"); /* We're going to just read rowids. */ @@ -10054,6 +10173,8 @@ int read_keys_and_merge_scans(THD *thd, { while ((result= cur_quick->get_next()) == HA_ERR_END_OF_FILE) { + if (intersection) + with_cpk_filter= filtered_scans->is_set(cur_quick->index); if (first_quick) { first_quick= FALSE; @@ -10084,18 +10205,10 @@ int read_keys_and_merge_scans(THD *thd, if (thd->killed) goto err; - if (intersection) - { - if (first_quick && - pk_quick_select && !pk_quick_select->row_in_ranges()) - continue; - } - else - { - /* skip row if it will be retrieved by clustered PK scan */ - if (pk_quick_select && pk_quick_select->row_in_ranges()) - continue; - } + if (with_cpk_filter && + pk_quick_select->row_in_ranges() != intersection ) + continue; + cur_quick->file->position(cur_quick->record); if (unique->unique_add((char*)cur_quick->file->ref)) goto err; @@ -10108,7 +10221,7 @@ int read_keys_and_merge_scans(THD *thd, */ result= unique->get(head); /* - index_merge currently doesn't support "using index" at all + index merge currently doesn't support "using index" at all */ head->disable_keyread(); init_read_record(read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE); @@ -10126,7 +10239,7 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() int result; DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::read_keys_and_merge"); result= read_keys_and_merge_scans(thd, head, quick_selects, pk_quick_select, - &read_record, FALSE, &unique); + &read_record, FALSE, NULL, &unique); doing_pk_scan= FALSE; DBUG_RETURN(result); } @@ -10173,8 +10286,8 @@ int QUICK_INDEX_INTERSECT_SELECT::read_keys_and_merge() int result; DBUG_ENTER("QUICK_INDEX_INTERSECT_SELECT::read_keys_and_merge"); result= read_keys_and_merge_scans(thd, head, quick_selects, pk_quick_select, - &read_record, TRUE, &unique); - doing_pk_scan= FALSE; + &read_record, TRUE, &filtered_scans, + &unique); DBUG_RETURN(result); } @@ -10188,7 +10301,6 @@ int QUICK_INDEX_INTERSECT_SELECT::get_next() result= HA_ERR_END_OF_FILE; end_read_record(&read_record); free_io_cache(head); - /* All rows from Unique have been retrieved, do a clustered PK scan */ } DBUG_RETURN(result); @@ -13391,7 +13503,7 @@ void QUICK_RANGE_SELECT::dbug_dump(int indent, bool verbose) /* purecov: end */ } -void QUICK_INDEX_MERGE_SELECT::dbug_dump(int indent, bool verbose) +void QUICK_INDEX_SORT_SELECT::dbug_dump(int indent, bool verbose) { List_iterator_fast it(quick_selects); QUICK_RANGE_SELECT *quick; @@ -13407,22 +13519,6 @@ void QUICK_INDEX_MERGE_SELECT::dbug_dump(int indent, bool verbose) fprintf(DBUG_FILE, "%*s}\n", indent, ""); } -void QUICK_INDEX_INTERSECT_SELECT::dbug_dump(int indent, bool verbose) -{ - List_iterator_fast it(quick_selects); - QUICK_RANGE_SELECT *quick; - fprintf(DBUG_FILE, "%*squick index_intersect select\n", indent, ""); - fprintf(DBUG_FILE, "%*smerged scans {\n", indent, ""); - while ((quick= it++)) - quick->dbug_dump(indent+2, verbose); - if (pk_quick_select) - { - fprintf(DBUG_FILE, "%*sclustered PK quick:\n", indent, ""); - pk_quick_select->dbug_dump(indent+2, verbose); - } - fprintf(DBUG_FILE, "%*s}\n", indent, ""); -} - void QUICK_ROR_INTERSECT_SELECT::dbug_dump(int indent, bool verbose) { List_iterator_fast it(quick_selects); diff --git a/sql/opt_range.h b/sql/opt_range.h index d894cfaf91d..32a88dd0193 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -328,6 +328,7 @@ public: selects output and/or can produce output suitable for merging. */ virtual void add_info_string(String *str) {} + /* Return 1 if any index used by this quick select uses field which is marked in passed bitmap. @@ -406,9 +407,11 @@ protected: QUICK_RANGE_SELECT *pk_quick_select, READ_RECORD *read_record, bool intersection, + key_map *filtered_scans, Unique **unique_ptr); friend class QUICK_SELECT_DESC; + friend class QUICK_INDEX_SORT_SELECT; friend class QUICK_INDEX_MERGE_SELECT; friend class QUICK_INDEX_INTERSECT_SELECT; friend class QUICK_ROR_INTERSECT_SELECT; @@ -464,40 +467,44 @@ public: /* - QUICK_INDEX_MERGE_SELECT - index_merge access method quick select. + QUICK_INDEX_SORT_SELECT is the base class for the common functionality of: + - QUICK_INDEX_MERGE_SELECT, access based on multi-index merge/union + - QUICK_INDEX_INTERSECT_SELECT, access based on multi-index intersection + - QUICK_INDEX_MERGE_SELECT uses + QUICK_INDEX_SORT_SELECT uses * QUICK_RANGE_SELECTs to get rows - * Unique class to remove duplicate rows + * Unique class + - to remove duplicate rows for QUICK_INDEX_MERGE_SELECT + - to intersect rows for QUICK_INDEX_INTERSECT_SELECT INDEX MERGE OPTIMIZER - Current implementation doesn't detect all cases where index_merge could + Current implementation doesn't detect all cases where index merge could be used, in particular: - * index_merge will never be used if range scan is possible (even if - range scan is more expensive) - * index_merge+'using index' is not supported (this the consequence of + * index merge+'using index' is not supported (this the consequence of the above restriction) * If WHERE part contains complex nested AND and OR conditions, some ways - to retrieve rows using index_merge will not be considered. The choice + to retrieve rows using index merge will not be considered. The choice of read plan may depend on the order of conjuncts/disjuncts in WHERE part of the query, see comments near imerge_list_or_list and SEL_IMERGE::or_sel_tree_with_checks functions for details. - * There is no "index_merge_ref" method (but index_merge on non-first + * There is no "index_merge_ref" method (but index merge on non-first table in join is possible with 'range checked for each record'). - See comments around SEL_IMERGE class and test_quick_select for more - details. ROW RETRIEVAL ALGORITHM - index_merge uses Unique class for duplicates removal. index_merge takes - advantage of Clustered Primary Key (CPK) if the table has one. - The index_merge algorithm consists of two phases: + index merge/intersection uses Unique class for duplicates removal. + index merge/intersection takes advantage of Clustered Primary Key (CPK) + if the table has one. + The index merge/intersection algorithm consists of two phases: + + Phase 1 + (implemented by a QUICK_INDEX_MERGE_SELECT::read_keys_and_merge call): - Phase 1 (implemented in QUICK_INDEX_MERGE_SELECT::prepare_unique): prepare() { activate 'index only'; @@ -511,32 +518,31 @@ public: deactivate 'index only'; } - Phase 2 (implemented as sequence of QUICK_INDEX_MERGE_SELECT::get_next - calls): + Phase 2 + (implemented as sequence of QUICK_INDEX_MERGE_SELECT::get_next calls): fetch() { - retrieve all rows from row pointers stored in Unique; + retrieve all rows from row pointers stored in Unique + (merging/intersecting them); free Unique; - retrieve all rows for CPK scan; + if (! intersection) + retrieve all rows for CPK scan; } */ -class QUICK_INDEX_MERGE_SELECT : public QUICK_SELECT_I +class QUICK_INDEX_SORT_SELECT : public QUICK_SELECT_I { +protected: Unique *unique; public: - QUICK_INDEX_MERGE_SELECT(THD *thd, TABLE *table); - ~QUICK_INDEX_MERGE_SELECT(); + QUICK_INDEX_SORT_SELECT(THD *thd, TABLE *table); + ~QUICK_INDEX_SORT_SELECT(); int init(); int reset(void); - int get_next(); bool reverse_sorted() { return false; } bool unique_key_range() { return false; } - int get_type() { return QS_TYPE_INDEX_MERGE; } - void add_keys_and_lengths(String *key_names, String *used_lengths); - void add_info_string(String *str); bool is_keys_used(const MY_BITMAP *fields); #ifndef DBUG_OFF void dbug_dump(int indent, bool verbose); @@ -544,60 +550,54 @@ public: bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range); - /* range quick selects this index_merge read consists of */ + /* range quick selects this index merge/intersect consists of */ List quick_selects; /* quick select that uses clustered primary key (NULL if none) */ QUICK_RANGE_SELECT* pk_quick_select; - /* true if this select is currently doing a clustered PK scan */ - bool doing_pk_scan; - MEM_ROOT alloc; THD *thd; - int read_keys_and_merge(); + virtual int read_keys_and_merge()= 0; /* used to get rows collected in Unique */ READ_RECORD read_record; }; -class QUICK_INDEX_INTERSECT_SELECT : public QUICK_SELECT_I -{ - Unique *unique; -public: - QUICK_INDEX_INTERSECT_SELECT(THD *thd, TABLE *table); - ~QUICK_INDEX_INTERSECT_SELECT(); - int init(); - int reset(void); - int get_next(); - bool reverse_sorted() { return false; } - bool unique_key_range() { return false; } + +class QUICK_INDEX_MERGE_SELECT : public QUICK_INDEX_SORT_SELECT +{ +private: + /* true if this select is currently doing a clustered PK scan */ + bool doing_pk_scan; +protected: + int read_keys_and_merge(); + +public: + QUICK_INDEX_MERGE_SELECT(THD *thd, TABLE *table) + :QUICK_INDEX_SORT_SELECT(thd, table) {} + + int get_next(); + int get_type() { return QS_TYPE_INDEX_MERGE; } + void add_keys_and_lengths(String *key_names, String *used_lengths); + void add_info_string(String *str); +}; + +class QUICK_INDEX_INTERSECT_SELECT : public QUICK_INDEX_SORT_SELECT +{ +protected: + int read_keys_and_merge(); + +public: + QUICK_INDEX_INTERSECT_SELECT(THD *thd, TABLE *table) + :QUICK_INDEX_SORT_SELECT(thd, table) {} + + key_map filtered_scans; + int get_next(); int get_type() { return QS_TYPE_INDEX_INTERSECT; } void add_keys_and_lengths(String *key_names, String *used_lengths); void add_info_string(String *str); - bool is_keys_used(const MY_BITMAP *fields); -#ifndef DBUG_OFF - void dbug_dump(int indent, bool verbose); -#endif - - bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range); - - /* range quick selects this index_merge read consists of */ - List quick_selects; - - /* quick select that uses clustered primary key (NULL if none) */ - QUICK_RANGE_SELECT* pk_quick_select; - - /* true if this select is currently doing a clustered PK scan */ - bool doing_pk_scan; - - MEM_ROOT alloc; - THD *thd; - int read_keys_and_merge(); - - /* used to get rows collected in Unique */ - READ_RECORD read_record; }; diff --git a/sql/sql_class.h b/sql/sql_class.h index 6d51e972c85..ed66d8dccea 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2998,7 +2998,7 @@ class Unique :public Sql_alloc bool flush(); uint size; uint full_size; - uint min_dupl_count; + uint min_dupl_count; /* always 0 for unions, > 0 for intersections */ public: ulong elements; @@ -3022,6 +3022,7 @@ public: bool get(TABLE *table); + /* Cost of searching for an element in the tree */ inline static double get_search_cost(uint tree_elems, uint compare_factor) { return log((double) tree_elems) / (compare_factor * M_LN2); From 6c958d6e80f681c207f4298b754c8b18170d3224 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 20 Dec 2010 19:19:24 +0100 Subject: [PATCH 32/33] bug#683112 Maria 5.2 incorrectly reports "(using password: NO)" even when password is specified set thd->password appropriately also for cases when a user was not found. --- mysql-test/r/connect.result | 4 ++++ mysql-test/t/connect.test | 13 +++++++++++++ sql/sql_acl.cc | 17 ++++++++++------- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/connect.result b/mysql-test/r/connect.result index 690a6fb3bc3..00602093425 100644 --- a/mysql-test/r/connect.result +++ b/mysql-test/r/connect.result @@ -237,5 +237,9 @@ ERROR 28000: Access denied for user 'mysqltest_up2'@'localhost' (using password: select user(), current_user(); user() current_user() mysqltest_up2@localhost mysqltest_up2@% +connect(localhost,mysqltest_nouser,newpw,test,MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'mysqltest_nouser'@'localhost' (using password: YES) +connect(localhost,mysqltest_nouser,,test,MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'mysqltest_nouser'@'localhost' (using password: NO) DROP USER mysqltest_up1@'%'; DROP USER mysqltest_up2@'%'; diff --git a/mysql-test/t/connect.test b/mysql-test/t/connect.test index a8c8b659c3c..8fbdd709364 100644 --- a/mysql-test/t/connect.test +++ b/mysql-test/t/connect.test @@ -352,6 +352,19 @@ connection pcon4; select user(), current_user(); disconnect pcon4; +# +# lpbug#683112 Maria 5.2 incorrectly reports "(using password: NO)" +# even when password is specified +# +# test "access denied" error for nonexisting user with and without a password +# +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error ER_ACCESS_DENIED_ERROR +connect(pcon5,localhost,mysqltest_nouser,newpw,,$MASTER_MYPORT,); +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error ER_ACCESS_DENIED_ERROR +connect(pcon5,localhost,mysqltest_nouser,,,$MASTER_MYPORT,); + connection default; DROP USER mysqltest_up1@'%'; DROP USER mysqltest_up2@'%'; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 87e27d68b98..9b1d0df4251 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -6980,16 +6980,16 @@ struct MPVIO_EXT : public MYSQL_PLUGIN_VIO a helper function to report an access denied error in all the proper places */ -static void login_failed_error(THD *thd, bool passwd_used) +static void login_failed_error(THD *thd) { my_error(ER_ACCESS_DENIED_ERROR, MYF(0), thd->main_security_ctx.user, thd->main_security_ctx.host_or_ip, - passwd_used ? ER(ER_YES) : ER(ER_NO)); + thd->password ? ER(ER_YES) : ER(ER_NO)); general_log_print(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR), thd->main_security_ctx.user, thd->main_security_ctx.host_or_ip, - passwd_used ? ER(ER_YES) : ER(ER_NO)); + thd->password ? ER(ER_YES) : ER(ER_NO)); status_var_increment(thd->status_var.access_denied_errors); /* Log access denied messages to the error log when log-warnings = 2 @@ -7001,7 +7001,7 @@ static void login_failed_error(THD *thd, bool passwd_used) sql_print_warning(ER(ER_ACCESS_DENIED_ERROR), thd->main_security_ctx.user, thd->main_security_ctx.host_or_ip, - passwd_used ? ER(ER_YES) : ER(ER_NO)); + thd->password ? ER(ER_YES) : ER(ER_NO)); } } @@ -7266,7 +7266,7 @@ static bool find_mpvio_user(MPVIO_EXT *mpvio, Security_context *sctx) if (!mpvio->acl_user) { - login_failed_error(mpvio->thd, 0); + login_failed_error(mpvio->thd); return 1; } @@ -7583,8 +7583,11 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, return packet_error; } + thd->password= passwd_len > 0; if (find_mpvio_user(mpvio, sctx)) + { return packet_error; + } if (thd->client_capabilities & CLIENT_PLUGIN_AUTH) { @@ -8072,7 +8075,7 @@ bool acl_authenticate(THD *thd, uint connect_errors, uint com_change_user_pkt_le DBUG_ASSERT(mpvio.status == MPVIO_EXT::FAILURE); if (!thd->is_error()) - login_failed_error(thd, thd->password); + login_failed_error(thd); DBUG_RETURN(1); } @@ -8092,7 +8095,7 @@ bool acl_authenticate(THD *thd, uint connect_errors, uint com_change_user_pkt_le */ if (acl_check_ssl(thd, acl_user)) { - login_failed_error(thd, thd->password); + login_failed_error(thd); DBUG_RETURN(1); } From 6f2db629a0b251e141bc29f2f1c3e3ac99a4eaa5 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Wed, 22 Dec 2010 18:45:44 -0800 Subject: [PATCH 33/33] Post-review fixes. --- mysql-test/r/index_intersect.result | 522 ++++++++++----------- mysql-test/r/index_intersect_innodb.result | 148 +++--- mysql-test/r/index_merge_myisam.result | 12 +- mysql-test/t/index_intersect.test | 38 +- sql/mysql_priv.h | 4 +- sql/mysqld.cc | 2 +- sql/opt_range.cc | 25 +- sql/sql_select.cc | 3 +- 8 files changed, 375 insertions(+), 379 deletions(-) diff --git a/mysql-test/r/index_intersect.result b/mysql-test/r/index_intersect.result index fdb4885e071..9a968468757 100644 --- a/mysql-test/r/index_intersect.result +++ b/mysql-test/r/index_intersect.result @@ -83,98 +83,77 @@ id select_type table type possible_keys key key_len ref rows Extra SELECT * FROM City USE INDEX () WHERE Name LIKE 'C%' AND Population > 1000000; ID Name Country Population -71 Córdoba ARG 1157507 -151 Chittagong BGD 1392860 -212 Curitiba BRA 1584232 -608 Cairo EGY 6789479 -712 Cape Town ZAF 2352121 -926 Conakry GIN 1090610 1026 Calcutta [Kolkata] IND 4399819 1027 Chennai (Madras) IND 3841396 +151 Chittagong BGD 1392860 1892 Chongqing CHN 6351600 1898 Chengdu CHN 3361500 1900 Changchun CHN 2812000 1910 Changsha CHN 1809800 +212 Curitiba BRA 1584232 2258 Cali COL 2077386 2485 Casablanca MAR 2940623 2515 Ciudad de México MEX 8591309 3539 Caracas VEN 1975294 3795 Chicago USA 2896016 +608 Cairo EGY 6789479 +71 Córdoba ARG 1157507 +712 Cape Town ZAF 2352121 +926 Conakry GIN 1090610 SELECT * FROM City WHERE Name LIKE 'C%' AND Population > 1000000; ID Name Country Population -71 Córdoba ARG 1157507 -151 Chittagong BGD 1392860 -212 Curitiba BRA 1584232 -608 Cairo EGY 6789479 -712 Cape Town ZAF 2352121 -926 Conakry GIN 1090610 1026 Calcutta [Kolkata] IND 4399819 1027 Chennai (Madras) IND 3841396 +151 Chittagong BGD 1392860 1892 Chongqing CHN 6351600 1898 Chengdu CHN 3361500 1900 Changchun CHN 2812000 1910 Changsha CHN 1809800 +212 Curitiba BRA 1584232 2258 Cali COL 2077386 2485 Casablanca MAR 2940623 2515 Ciudad de México MEX 8591309 3539 Caracas VEN 1975294 3795 Chicago USA 2896016 +608 Cairo EGY 6789479 +71 Córdoba ARG 1157507 +712 Cape Town ZAF 2352121 +926 Conakry GIN 1090610 SELECT * FROM City USE INDEX () WHERE Name LIKE 'M%' AND Population > 1500000; ID Name Country Population -131 Melbourne AUS 2865329 -653 Madrid ESP 2879052 -766 Manila PHL 1581082 -942 Medan IDN 1843919 1024 Mumbai (Bombay) IND 10500000 +131 Melbourne AUS 2865329 1381 Mashhad IRN 1887405 2259 Medellín COL 1861265 3520 Minsk BLR 1674000 3580 Moscow RUS 8389200 +653 Madrid ESP 2879052 +766 Manila PHL 1581082 +942 Medan IDN 1843919 SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 1500000; ID Name Country Population -131 Melbourne AUS 2865329 -653 Madrid ESP 2879052 -766 Manila PHL 1581082 -942 Medan IDN 1843919 1024 Mumbai (Bombay) IND 10500000 +131 Melbourne AUS 2865329 1381 Mashhad IRN 1887405 2259 Medellín COL 1861265 3520 Minsk BLR 1674000 3580 Moscow RUS 8389200 +653 Madrid ESP 2879052 +766 Manila PHL 1581082 +942 Medan IDN 1843919 SELECT * FROM City USE INDEX () WHERE Name LIKE 'M%' AND Population > 300000; ID Name Country Population -77 Mar del Plata ARG 512880 -80 Merlo ARG 463846 -83 Moreno ARG 356993 -87 Morón ARG 349246 -131 Melbourne AUS 2865329 -215 Manaus BRA 1255049 -223 Maceió BRA 786288 -250 Mauá BRA 375055 -256 Moji das Cruzes BRA 339194 -462 Manchester GBR 430000 -653 Madrid ESP 2879052 -658 Málaga ESP 530553 -661 Murcia ESP 353504 -766 Manila PHL 1581082 -778 Makati PHL 444867 -781 Marikina PHL 391170 -783 Muntinlupa PHL 379310 -786 Malabon PHL 338855 -942 Medan IDN 1843919 -947 Malang IDN 716862 -962 Manado IDN 332288 -963 Mataram IDN 306600 1024 Mumbai (Bombay) IND 10500000 1042 Madurai IND 977856 1051 Meerut IND 753778 1074 Mysore IND 480692 1081 Moradabad IND 429214 1098 Malegaon IND 342595 +131 Melbourne AUS 2865329 1366 Mosul IRQ 879000 1381 Mashhad IRN 1887405 1465 Milano ITA 1300977 @@ -187,6 +166,8 @@ ID Name Country Population 1882 Mombasa KEN 461753 1945 Mudanjiang CHN 570000 2005 Ma´anshan CHN 305421 +215 Manaus BRA 1255049 +223 Maceió BRA 786288 2259 Medellín COL 1861265 2267 Manizales COL 337580 2300 Mbuji-Mayi COD 806475 @@ -195,12 +176,14 @@ ID Name Country Population 2454 Macao MAC 437500 2487 Marrakech MAR 621914 2491 Meknès MAR 460000 +250 Mauá BRA 375055 2523 Monterrey MEX 1108499 2526 Mexicali MEX 764902 2530 Mérida MEX 703324 2537 Morelia MEX 619958 2554 Matamoros MEX 416428 2557 Mazatlán MEX 380265 +256 Moji das Cruzes BRA 339194 2698 Maputo MOZ 1018938 2699 Matola MOZ 424662 2711 Mandalay MMR 885300 @@ -235,97 +218,114 @@ ID Name Country Population 3834 Mesa USA 396375 3837 Minneapolis USA 382618 3839 Miami USA 362470 +462 Manchester GBR 430000 +653 Madrid ESP 2879052 +658 Málaga ESP 530553 +661 Murcia ESP 353504 +766 Manila PHL 1581082 +77 Mar del Plata ARG 512880 +778 Makati PHL 444867 +781 Marikina PHL 391170 +783 Muntinlupa PHL 379310 +786 Malabon PHL 338855 +80 Merlo ARG 463846 +83 Moreno ARG 356993 +87 Morón ARG 349246 +942 Medan IDN 1843919 +947 Malang IDN 716862 +962 Manado IDN 332288 +963 Mataram IDN 306600 SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 300000; ID Name Country Population -2454 Macao MAC 437500 -223 Maceió BRA 786288 -1578 Machida JPN 364197 -653 Madrid ESP 2879052 +1024 Mumbai (Bombay) IND 10500000 1042 Madurai IND 977856 -3622 Magnitogorsk RUS 427900 -3636 Mahat?kala RUS 332800 -2757 Maiduguri NGA 320000 -778 Makati PHL 444867 -3438 Makijivka UKR 384000 -786 Malabon PHL 338855 -658 Málaga ESP 530553 -947 Malang IDN 716862 -3371 Malatya TUR 330312 +1051 Meerut IND 753778 +1074 Mysore IND 480692 +1081 Moradabad IND 429214 1098 Malegaon IND 342595 -962 Manado IDN 332288 -2734 Managua NIC 959000 +131 Melbourne AUS 2865329 +1366 Mosul IRQ 879000 +1381 Mashhad IRN 1887405 +1465 Milano ITA 1300977 +1559 Matsuyama JPN 466133 +1560 Matsudo JPN 461126 +1578 Machida JPN 364197 +1595 Miyazaki JPN 303784 +1810 Montréal CAN 1016376 +1816 Mississauga CAN 608072 +1882 Mombasa KEN 461753 +1945 Mudanjiang CHN 570000 +2005 Ma´anshan CHN 305421 215 Manaus BRA 1255049 -462 Manchester GBR 430000 -2711 Mandalay MMR 885300 -766 Manila PHL 1581082 +223 Maceió BRA 786288 +2259 Medellín COL 1861265 2267 Manizales COL 337580 -3086 Mannheim DEU 307730 +2300 Mbuji-Mayi COD 806475 +2348 Masan KOR 441242 +2440 Monrovia LBR 850000 +2454 Macao MAC 437500 +2487 Marrakech MAR 621914 +2491 Meknès MAR 460000 +250 Mauá BRA 375055 +2523 Monterrey MEX 1108499 +2526 Mexicali MEX 764902 +2530 Mérida MEX 703324 +2537 Morelia MEX 619958 +2554 Matamoros MEX 416428 +2557 Mazatlán MEX 380265 +256 Moji das Cruzes BRA 339194 2698 Maputo MOZ 1018938 -77 Mar del Plata ARG 512880 +2699 Matola MOZ 424662 +2711 Mandalay MMR 885300 +2712 Moulmein (Mawlamyine) MMR 307900 +2734 Managua NIC 959000 +2756 Mushin NGA 333200 +2757 Maiduguri NGA 320000 +2826 Multan PAK 1182441 +2975 Marseille FRA 798430 +3070 Munich [München] DEU 1194560 +3086 Mannheim DEU 307730 +3175 Mekka SAU 965700 +3176 Medina SAU 608300 +3214 Mogadishu SOM 997000 +3364 Mersin (Içel) TUR 587212 +3371 Malatya TUR 330312 +3434 Mykolajiv UKR 508000 +3435 Mariupol UKR 490000 +3438 Makijivka UKR 384000 +3492 Montevideo URY 1236000 +3520 Minsk BLR 1674000 +3522 Mogiljov BLR 356000 3540 Maracaíbo VEN 1304776 3545 Maracay VEN 444443 -781 Marikina PHL 391170 -3435 Mariupol UKR 490000 -2487 Marrakech MAR 621914 -2975 Marseille FRA 798430 -2348 Masan KOR 441242 -1381 Mashhad IRN 1887405 -2554 Matamoros MEX 416428 -963 Mataram IDN 306600 -2699 Matola MOZ 424662 -1560 Matsudo JPN 461126 -1559 Matsuyama JPN 466133 3547 Maturín VEN 319726 -250 Mauá BRA 375055 -2557 Mazatlán MEX 380265 -2005 Ma´anshan CHN 305421 -2300 Mbuji-Mayi COD 806475 -942 Medan IDN 1843919 -2259 Medellín COL 1861265 -3176 Medina SAU 608300 -1051 Meerut IND 753778 -3175 Mekka SAU 965700 -2491 Meknès MAR 460000 -131 Melbourne AUS 2865329 +3580 Moscow RUS 8389200 +3622 Magnitogorsk RUS 427900 +3625 Murmansk RUS 376300 +3636 Mahat?kala RUS 332800 3810 Memphis USA 650100 -2530 Mérida MEX 703324 -80 Merlo ARG 463846 -3364 Mersin (Içel) TUR 587212 -3834 Mesa USA 396375 -2526 Mexicali MEX 764902 -3839 Miami USA 362470 -1465 Milano ITA 1300977 3811 Milwaukee USA 596974 +3834 Mesa USA 396375 3837 Minneapolis USA 382618 -3520 Minsk BLR 1674000 -1816 Mississauga CAN 608072 -1595 Miyazaki JPN 303784 -3214 Mogadishu SOM 997000 -3522 Mogiljov BLR 356000 -256 Moji das Cruzes BRA 339194 -1882 Mombasa KEN 461753 -2440 Monrovia LBR 850000 -2523 Monterrey MEX 1108499 -3492 Montevideo URY 1236000 -1810 Montréal CAN 1016376 -1081 Moradabad IND 429214 -2537 Morelia MEX 619958 +3839 Miami USA 362470 +462 Manchester GBR 430000 +653 Madrid ESP 2879052 +658 Málaga ESP 530553 +661 Murcia ESP 353504 +766 Manila PHL 1581082 +77 Mar del Plata ARG 512880 +778 Makati PHL 444867 +781 Marikina PHL 391170 +783 Muntinlupa PHL 379310 +786 Malabon PHL 338855 +80 Merlo ARG 463846 83 Moreno ARG 356993 87 Morón ARG 349246 -3580 Moscow RUS 8389200 -1366 Mosul IRQ 879000 -2712 Moulmein (Mawlamyine) MMR 307900 -1945 Mudanjiang CHN 570000 -2826 Multan PAK 1182441 -1024 Mumbai (Bombay) IND 10500000 -3070 Munich [München] DEU 1194560 -783 Muntinlupa PHL 379310 -661 Murcia ESP 353504 -3625 Murmansk RUS 376300 -2756 Mushin NGA 333200 -3434 Mykolajiv UKR 508000 -1074 Mysore IND 480692 +942 Medan IDN 1843919 +947 Malang IDN 716862 +962 Manado IDN 332288 +963 Mataram IDN 306600 SELECT * FROM City USE INDEX () WHERE Name LIKE 'M%' AND Population > 5000000; ID Name Country Population @@ -486,30 +486,30 @@ SELECT * FROM City USE INDEX () WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; ID Name Country Population 1 Kabul AFG 1780000 -56 Luanda AGO 2022000 -69 Buenos Aires ARG 2982146 -70 La Matanza ARG 1266461 -71 Córdoba ARG 1157507 126 Yerevan ARM 1248700 130 Sydney AUS 3276207 131 Melbourne AUS 2865329 132 Brisbane AUS 1291117 133 Perth AUS 1096829 144 Baku AZE 1787800 +56 Luanda AGO 2022000 +69 Buenos Aires ARG 2982146 +70 La Matanza ARG 1266461 +71 Córdoba ARG 1157507 SELECT * FROM City WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; ID Name Country Population 1 Kabul AFG 1780000 -56 Luanda AGO 2022000 -69 Buenos Aires ARG 2982146 -70 La Matanza ARG 1266461 -71 Córdoba ARG 1157507 126 Yerevan ARM 1248700 130 Sydney AUS 3276207 131 Melbourne AUS 2865329 132 Brisbane AUS 1291117 133 Perth AUS 1096829 144 Baku AZE 1787800 +56 Luanda AGO 2022000 +69 Buenos Aires ARG 2982146 +70 La Matanza ARG 1266461 +71 Córdoba ARG 1157507 SELECT * FROM City USE INDEX () WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'L%'; ID Name Country Population @@ -650,72 +650,72 @@ SELECT * FROM City WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 AND Country BETWEEN 'S' AND 'Z' ; ID Name Country Population -3176 Medina SAU 608300 -3363 Konya TUR 628364 -3810 Memphis USA 650100 -3809 Baltimore USA 651154 -3808 Austin USA 656562 -3543 Ciudad Guayana VEN 663713 -3349 Tunis TUN 690600 -3226 Sharq al-Nil SDN 700887 -3433 Kryvyi Rig UKR 703000 -3807 Columbus USA 711470 -3266 Tainan TWN 728060 -3806 Jacksonville USA 735167 3048 Stockholm SWE 750348 -3805 San Francisco USA 776733 -3771 Haiphong VNM 783133 -3198 Dakar SEN 785071 -3432 Lviv UKR 788000 -3362 Gaziantep TUR 789056 -3804 Indianapolis USA 791926 -3542 Valencia VEN 794246 -3431 Zaporizzja UKR 848000 -3207 Freetown SLE 850000 -3197 Pikine SEN 855287 -3541 Barquisimeto VEN 877239 -3425 Kampala UGA 890800 -3803 San Jose USA 894943 -3265 Taichung TWN 940589 -3225 Khartum SDN 947483 -3802 Detroit USA 951270 -3175 Mekka SAU 965700 -3214 Mogadishu SOM 997000 -3430 Odesa UKR 1011000 -3429 Donetsk UKR 1050000 -3361 Bursa TUR 1095842 -3428 Dnipropetrovsk UKR 1103000 -3360 Adana TUR 1131198 -3801 San Antonio USA 1144646 -3800 Dallas USA 1188580 -3799 San Diego USA 1223400 -3492 Montevideo URY 1236000 -3251 Aleppo SYR 1261983 -3224 Omdurman SDN 1271403 -3540 Maracaíbo VEN 1304776 -3798 Phoenix USA 1321045 -3250 Damascus SYR 1347000 -3770 Hanoi VNM 1410000 -3264 Kaohsiung TWN 1475505 -3427 Harkova [Harkiv] UKR 1500000 -3797 Philadelphia USA 1517550 -3305 Dar es Salaam TZA 1747000 -3796 Houston USA 1953631 -3539 Caracas VEN 1975294 -3174 Jedda SAU 2046300 -3503 Toskent UZB 2117500 -3359 Izmir TUR 2130359 -3426 Kyiv UKR 2624000 -3263 Taipei TWN 2641312 -3795 Chicago USA 2896016 -3358 Ankara TUR 3038159 3173 Riyadh SAU 3324000 -3794 Los Angeles USA 3694820 -3769 Ho Chi Minh City VNM 3980000 +3174 Jedda SAU 2046300 +3175 Mekka SAU 965700 +3176 Medina SAU 608300 +3197 Pikine SEN 855287 +3198 Dakar SEN 785071 +3207 Freetown SLE 850000 3208 Singapore SGP 4017733 +3214 Mogadishu SOM 997000 +3224 Omdurman SDN 1271403 +3225 Khartum SDN 947483 +3226 Sharq al-Nil SDN 700887 +3250 Damascus SYR 1347000 +3251 Aleppo SYR 1261983 +3263 Taipei TWN 2641312 +3264 Kaohsiung TWN 1475505 +3265 Taichung TWN 940589 +3266 Tainan TWN 728060 +3305 Dar es Salaam TZA 1747000 3320 Bangkok THA 6320174 -3793 New York USA 8008278 +3349 Tunis TUN 690600 3357 Istanbul TUR 8787958 +3358 Ankara TUR 3038159 +3359 Izmir TUR 2130359 +3360 Adana TUR 1131198 +3361 Bursa TUR 1095842 +3362 Gaziantep TUR 789056 +3363 Konya TUR 628364 +3425 Kampala UGA 890800 +3426 Kyiv UKR 2624000 +3427 Harkova [Harkiv] UKR 1500000 +3428 Dnipropetrovsk UKR 1103000 +3429 Donetsk UKR 1050000 +3430 Odesa UKR 1011000 +3431 Zaporizzja UKR 848000 +3432 Lviv UKR 788000 +3433 Kryvyi Rig UKR 703000 +3492 Montevideo URY 1236000 +3503 Toskent UZB 2117500 +3539 Caracas VEN 1975294 +3540 Maracaíbo VEN 1304776 +3541 Barquisimeto VEN 877239 +3542 Valencia VEN 794246 +3543 Ciudad Guayana VEN 663713 +3769 Ho Chi Minh City VNM 3980000 +3770 Hanoi VNM 1410000 +3771 Haiphong VNM 783133 +3793 New York USA 8008278 +3794 Los Angeles USA 3694820 +3795 Chicago USA 2896016 +3796 Houston USA 1953631 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3799 San Diego USA 1223400 +3800 Dallas USA 1188580 +3801 San Antonio USA 1144646 +3802 Detroit USA 951270 +3803 San Jose USA 894943 +3804 Indianapolis USA 791926 +3805 San Francisco USA 776733 +3806 Jacksonville USA 735167 +3807 Columbus USA 711470 +3808 Austin USA 656562 +3809 Baltimore USA 651154 +3810 Memphis USA 650100 SET SESSION sort_buffer_size = 2048; EXPLAIN SELECT * FROM City WHERE @@ -751,23 +751,23 @@ id select_type table type possible_keys key key_len ref rows Extra SELECT * FROM City WHERE Name LIKE 'C%' AND Population > 1000000; ID Name Country Population -71 Córdoba ARG 1157507 -151 Chittagong BGD 1392860 -212 Curitiba BRA 1584232 -608 Cairo EGY 6789479 -712 Cape Town ZAF 2352121 -926 Conakry GIN 1090610 1026 Calcutta [Kolkata] IND 4399819 1027 Chennai (Madras) IND 3841396 +151 Chittagong BGD 1392860 1892 Chongqing CHN 6351600 1898 Chengdu CHN 3361500 1900 Changchun CHN 2812000 1910 Changsha CHN 1809800 +212 Curitiba BRA 1584232 2258 Cali COL 2077386 2485 Casablanca MAR 2940623 2515 Ciudad de México MEX 8591309 3539 Caracas VEN 1975294 3795 Chicago USA 2896016 +608 Cairo EGY 6789479 +71 Córdoba ARG 1157507 +712 Cape Town ZAF 2352121 +926 Conakry GIN 1090610 SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 1500000; ID Name Country Population @@ -814,72 +814,72 @@ SELECT * FROM City WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 AND Country BETWEEN 'S' AND 'Z'; ID Name Country Population -3176 Medina SAU 608300 -3363 Konya TUR 628364 -3810 Memphis USA 650100 -3809 Baltimore USA 651154 -3808 Austin USA 656562 -3543 Ciudad Guayana VEN 663713 -3349 Tunis TUN 690600 -3226 Sharq al-Nil SDN 700887 -3433 Kryvyi Rig UKR 703000 -3807 Columbus USA 711470 -3266 Tainan TWN 728060 -3806 Jacksonville USA 735167 3048 Stockholm SWE 750348 -3805 San Francisco USA 776733 -3771 Haiphong VNM 783133 -3198 Dakar SEN 785071 -3432 Lviv UKR 788000 -3362 Gaziantep TUR 789056 -3804 Indianapolis USA 791926 -3542 Valencia VEN 794246 -3431 Zaporizzja UKR 848000 -3207 Freetown SLE 850000 -3197 Pikine SEN 855287 -3541 Barquisimeto VEN 877239 -3425 Kampala UGA 890800 -3803 San Jose USA 894943 -3265 Taichung TWN 940589 -3225 Khartum SDN 947483 -3802 Detroit USA 951270 -3175 Mekka SAU 965700 -3214 Mogadishu SOM 997000 -3430 Odesa UKR 1011000 -3429 Donetsk UKR 1050000 -3361 Bursa TUR 1095842 -3428 Dnipropetrovsk UKR 1103000 -3360 Adana TUR 1131198 -3801 San Antonio USA 1144646 -3800 Dallas USA 1188580 -3799 San Diego USA 1223400 -3492 Montevideo URY 1236000 -3251 Aleppo SYR 1261983 -3224 Omdurman SDN 1271403 -3540 Maracaíbo VEN 1304776 -3798 Phoenix USA 1321045 -3250 Damascus SYR 1347000 -3770 Hanoi VNM 1410000 -3264 Kaohsiung TWN 1475505 -3427 Harkova [Harkiv] UKR 1500000 -3797 Philadelphia USA 1517550 -3305 Dar es Salaam TZA 1747000 -3796 Houston USA 1953631 -3539 Caracas VEN 1975294 -3174 Jedda SAU 2046300 -3503 Toskent UZB 2117500 -3359 Izmir TUR 2130359 -3426 Kyiv UKR 2624000 -3263 Taipei TWN 2641312 -3795 Chicago USA 2896016 -3358 Ankara TUR 3038159 3173 Riyadh SAU 3324000 -3794 Los Angeles USA 3694820 -3769 Ho Chi Minh City VNM 3980000 +3174 Jedda SAU 2046300 +3175 Mekka SAU 965700 +3176 Medina SAU 608300 +3197 Pikine SEN 855287 +3198 Dakar SEN 785071 +3207 Freetown SLE 850000 3208 Singapore SGP 4017733 +3214 Mogadishu SOM 997000 +3224 Omdurman SDN 1271403 +3225 Khartum SDN 947483 +3226 Sharq al-Nil SDN 700887 +3250 Damascus SYR 1347000 +3251 Aleppo SYR 1261983 +3263 Taipei TWN 2641312 +3264 Kaohsiung TWN 1475505 +3265 Taichung TWN 940589 +3266 Tainan TWN 728060 +3305 Dar es Salaam TZA 1747000 3320 Bangkok THA 6320174 -3793 New York USA 8008278 +3349 Tunis TUN 690600 3357 Istanbul TUR 8787958 +3358 Ankara TUR 3038159 +3359 Izmir TUR 2130359 +3360 Adana TUR 1131198 +3361 Bursa TUR 1095842 +3362 Gaziantep TUR 789056 +3363 Konya TUR 628364 +3425 Kampala UGA 890800 +3426 Kyiv UKR 2624000 +3427 Harkova [Harkiv] UKR 1500000 +3428 Dnipropetrovsk UKR 1103000 +3429 Donetsk UKR 1050000 +3430 Odesa UKR 1011000 +3431 Zaporizzja UKR 848000 +3432 Lviv UKR 788000 +3433 Kryvyi Rig UKR 703000 +3492 Montevideo URY 1236000 +3503 Toskent UZB 2117500 +3539 Caracas VEN 1975294 +3540 Maracaíbo VEN 1304776 +3541 Barquisimeto VEN 877239 +3542 Valencia VEN 794246 +3543 Ciudad Guayana VEN 663713 +3769 Ho Chi Minh City VNM 3980000 +3770 Hanoi VNM 1410000 +3771 Haiphong VNM 783133 +3793 New York USA 8008278 +3794 Los Angeles USA 3694820 +3795 Chicago USA 2896016 +3796 Houston USA 1953631 +3797 Philadelphia USA 1517550 +3798 Phoenix USA 1321045 +3799 San Diego USA 1223400 +3800 Dallas USA 1188580 +3801 San Antonio USA 1144646 +3802 Detroit USA 951270 +3803 San Jose USA 894943 +3804 Indianapolis USA 791926 +3805 San Francisco USA 776733 +3806 Jacksonville USA 735167 +3807 Columbus USA 711470 +3808 Austin USA 656562 +3809 Baltimore USA 651154 +3810 Memphis USA 650100 SET SESSION sort_buffer_size = default; DROP INDEX Country ON City; CREATE INDEX CountryID ON City(Country,ID); @@ -917,10 +917,10 @@ ID Name Country Population 2698 Maputo MOZ 1018938 2710 Rangoon (Yangon) MMR 3361700 SELECT * FROM City -WHERE Country LIKE 'M%' AND Population > 700000; +WHERE Country LIKE 'M%' AND Population > 1000000; ID Name Country Population +2464 Kuala Lumpur MYS 1297526 2485 Casablanca MAR 2940623 -2690 Chisinau MDA 719900 2515 Ciudad de México MEX 8591309 2516 Guadalajara MEX 1647720 2517 Ecatepec de Morelos MEX 1620303 @@ -931,18 +931,8 @@ ID Name Country Population 2522 León MEX 1133576 2523 Monterrey MEX 1108499 2524 Zapopan MEX 1002239 -2525 Naucalpan de Juárez MEX 857511 -2526 Mexicali MEX 764902 -2527 Culiacán MEX 744859 -2528 Acapulco de Juárez MEX 721011 -2529 Tlalnepantla de Baz MEX 720755 -2530 Mérida MEX 703324 -2482 Bamako MLI 809552 -2710 Rangoon (Yangon) MMR 3361700 -2711 Mandalay MMR 885300 -2696 Ulan Bator MNG 773700 2698 Maputo MOZ 1018938 -2464 Kuala Lumpur MYS 1297526 +2710 Rangoon (Yangon) MMR 3361700 SELECT * FROM City USE INDEX () WHERE Country='CHN' AND Population > 1500000; ID Name Country Population diff --git a/mysql-test/r/index_intersect_innodb.result b/mysql-test/r/index_intersect_innodb.result index 7b53761935a..8aca2f244e9 100644 --- a/mysql-test/r/index_intersect_innodb.result +++ b/mysql-test/r/index_intersect_innodb.result @@ -84,98 +84,77 @@ id select_type table type possible_keys key key_len ref rows Extra SELECT * FROM City USE INDEX () WHERE Name LIKE 'C%' AND Population > 1000000; ID Name Country Population -71 Córdoba ARG 1157507 -151 Chittagong BGD 1392860 -212 Curitiba BRA 1584232 -608 Cairo EGY 6789479 -712 Cape Town ZAF 2352121 -926 Conakry GIN 1090610 1026 Calcutta [Kolkata] IND 4399819 1027 Chennai (Madras) IND 3841396 +151 Chittagong BGD 1392860 1892 Chongqing CHN 6351600 1898 Chengdu CHN 3361500 1900 Changchun CHN 2812000 1910 Changsha CHN 1809800 +212 Curitiba BRA 1584232 2258 Cali COL 2077386 2485 Casablanca MAR 2940623 2515 Ciudad de México MEX 8591309 3539 Caracas VEN 1975294 3795 Chicago USA 2896016 +608 Cairo EGY 6789479 +71 Córdoba ARG 1157507 +712 Cape Town ZAF 2352121 +926 Conakry GIN 1090610 SELECT * FROM City WHERE Name LIKE 'C%' AND Population > 1000000; ID Name Country Population -71 Córdoba ARG 1157507 -151 Chittagong BGD 1392860 -212 Curitiba BRA 1584232 -608 Cairo EGY 6789479 -712 Cape Town ZAF 2352121 -926 Conakry GIN 1090610 1026 Calcutta [Kolkata] IND 4399819 1027 Chennai (Madras) IND 3841396 +151 Chittagong BGD 1392860 1892 Chongqing CHN 6351600 1898 Chengdu CHN 3361500 1900 Changchun CHN 2812000 1910 Changsha CHN 1809800 +212 Curitiba BRA 1584232 2258 Cali COL 2077386 2485 Casablanca MAR 2940623 2515 Ciudad de México MEX 8591309 3539 Caracas VEN 1975294 3795 Chicago USA 2896016 +608 Cairo EGY 6789479 +71 Córdoba ARG 1157507 +712 Cape Town ZAF 2352121 +926 Conakry GIN 1090610 SELECT * FROM City USE INDEX () WHERE Name LIKE 'M%' AND Population > 1500000; ID Name Country Population -131 Melbourne AUS 2865329 -653 Madrid ESP 2879052 -766 Manila PHL 1581082 -942 Medan IDN 1843919 1024 Mumbai (Bombay) IND 10500000 +131 Melbourne AUS 2865329 1381 Mashhad IRN 1887405 2259 Medellín COL 1861265 3520 Minsk BLR 1674000 3580 Moscow RUS 8389200 +653 Madrid ESP 2879052 +766 Manila PHL 1581082 +942 Medan IDN 1843919 SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 1500000; ID Name Country Population -131 Melbourne AUS 2865329 -653 Madrid ESP 2879052 -766 Manila PHL 1581082 -942 Medan IDN 1843919 1024 Mumbai (Bombay) IND 10500000 +131 Melbourne AUS 2865329 1381 Mashhad IRN 1887405 2259 Medellín COL 1861265 3520 Minsk BLR 1674000 3580 Moscow RUS 8389200 +653 Madrid ESP 2879052 +766 Manila PHL 1581082 +942 Medan IDN 1843919 SELECT * FROM City USE INDEX () WHERE Name LIKE 'M%' AND Population > 300000; ID Name Country Population -77 Mar del Plata ARG 512880 -80 Merlo ARG 463846 -83 Moreno ARG 356993 -87 Morón ARG 349246 -131 Melbourne AUS 2865329 -215 Manaus BRA 1255049 -223 Maceió BRA 786288 -250 Mauá BRA 375055 -256 Moji das Cruzes BRA 339194 -462 Manchester GBR 430000 -653 Madrid ESP 2879052 -658 Málaga ESP 530553 -661 Murcia ESP 353504 -766 Manila PHL 1581082 -778 Makati PHL 444867 -781 Marikina PHL 391170 -783 Muntinlupa PHL 379310 -786 Malabon PHL 338855 -942 Medan IDN 1843919 -947 Malang IDN 716862 -962 Manado IDN 332288 -963 Mataram IDN 306600 1024 Mumbai (Bombay) IND 10500000 1042 Madurai IND 977856 1051 Meerut IND 753778 1074 Mysore IND 480692 1081 Moradabad IND 429214 1098 Malegaon IND 342595 +131 Melbourne AUS 2865329 1366 Mosul IRQ 879000 1381 Mashhad IRN 1887405 1465 Milano ITA 1300977 @@ -188,6 +167,8 @@ ID Name Country Population 1882 Mombasa KEN 461753 1945 Mudanjiang CHN 570000 2005 Ma´anshan CHN 305421 +215 Manaus BRA 1255049 +223 Maceió BRA 786288 2259 Medellín COL 1861265 2267 Manizales COL 337580 2300 Mbuji-Mayi COD 806475 @@ -196,12 +177,14 @@ ID Name Country Population 2454 Macao MAC 437500 2487 Marrakech MAR 621914 2491 Meknès MAR 460000 +250 Mauá BRA 375055 2523 Monterrey MEX 1108499 2526 Mexicali MEX 764902 2530 Mérida MEX 703324 2537 Morelia MEX 619958 2554 Matamoros MEX 416428 2557 Mazatlán MEX 380265 +256 Moji das Cruzes BRA 339194 2698 Maputo MOZ 1018938 2699 Matola MOZ 424662 2711 Mandalay MMR 885300 @@ -236,37 +219,33 @@ ID Name Country Population 3834 Mesa USA 396375 3837 Minneapolis USA 382618 3839 Miami USA 362470 -SELECT * FROM City -WHERE Name LIKE 'M%' AND Population > 300000; -ID Name Country Population -77 Mar del Plata ARG 512880 -80 Merlo ARG 463846 -83 Moreno ARG 356993 -87 Morón ARG 349246 -131 Melbourne AUS 2865329 -215 Manaus BRA 1255049 -223 Maceió BRA 786288 -250 Mauá BRA 375055 -256 Moji das Cruzes BRA 339194 462 Manchester GBR 430000 653 Madrid ESP 2879052 658 Málaga ESP 530553 661 Murcia ESP 353504 766 Manila PHL 1581082 +77 Mar del Plata ARG 512880 778 Makati PHL 444867 781 Marikina PHL 391170 783 Muntinlupa PHL 379310 786 Malabon PHL 338855 +80 Merlo ARG 463846 +83 Moreno ARG 356993 +87 Morón ARG 349246 942 Medan IDN 1843919 947 Malang IDN 716862 962 Manado IDN 332288 963 Mataram IDN 306600 +SELECT * FROM City +WHERE Name LIKE 'M%' AND Population > 300000; +ID Name Country Population 1024 Mumbai (Bombay) IND 10500000 1042 Madurai IND 977856 1051 Meerut IND 753778 1074 Mysore IND 480692 1081 Moradabad IND 429214 1098 Malegaon IND 342595 +131 Melbourne AUS 2865329 1366 Mosul IRQ 879000 1381 Mashhad IRN 1887405 1465 Milano ITA 1300977 @@ -279,6 +258,8 @@ ID Name Country Population 1882 Mombasa KEN 461753 1945 Mudanjiang CHN 570000 2005 Ma´anshan CHN 305421 +215 Manaus BRA 1255049 +223 Maceió BRA 786288 2259 Medellín COL 1861265 2267 Manizales COL 337580 2300 Mbuji-Mayi COD 806475 @@ -287,12 +268,14 @@ ID Name Country Population 2454 Macao MAC 437500 2487 Marrakech MAR 621914 2491 Meknès MAR 460000 +250 Mauá BRA 375055 2523 Monterrey MEX 1108499 2526 Mexicali MEX 764902 2530 Mérida MEX 703324 2537 Morelia MEX 619958 2554 Matamoros MEX 416428 2557 Mazatlán MEX 380265 +256 Moji das Cruzes BRA 339194 2698 Maputo MOZ 1018938 2699 Matola MOZ 424662 2711 Mandalay MMR 885300 @@ -327,6 +310,23 @@ ID Name Country Population 3834 Mesa USA 396375 3837 Minneapolis USA 382618 3839 Miami USA 362470 +462 Manchester GBR 430000 +653 Madrid ESP 2879052 +658 Málaga ESP 530553 +661 Murcia ESP 353504 +766 Manila PHL 1581082 +77 Mar del Plata ARG 512880 +778 Makati PHL 444867 +781 Marikina PHL 391170 +783 Muntinlupa PHL 379310 +786 Malabon PHL 338855 +80 Merlo ARG 463846 +83 Moreno ARG 356993 +87 Morón ARG 349246 +942 Medan IDN 1843919 +947 Malang IDN 716862 +962 Manado IDN 332288 +963 Mataram IDN 306600 SELECT * FROM City USE INDEX () WHERE Name LIKE 'M%' AND Population > 5000000; ID Name Country Population @@ -487,30 +487,30 @@ SELECT * FROM City USE INDEX () WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; ID Name Country Population 1 Kabul AFG 1780000 -56 Luanda AGO 2022000 -69 Buenos Aires ARG 2982146 -70 La Matanza ARG 1266461 -71 Córdoba ARG 1157507 126 Yerevan ARM 1248700 130 Sydney AUS 3276207 131 Melbourne AUS 2865329 132 Brisbane AUS 1291117 133 Perth AUS 1096829 144 Baku AZE 1787800 +56 Luanda AGO 2022000 +69 Buenos Aires ARG 2982146 +70 La Matanza ARG 1266461 +71 Córdoba ARG 1157507 SELECT * FROM City WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; ID Name Country Population 1 Kabul AFG 1780000 -56 Luanda AGO 2022000 -69 Buenos Aires ARG 2982146 -70 La Matanza ARG 1266461 -71 Córdoba ARG 1157507 126 Yerevan ARM 1248700 130 Sydney AUS 3276207 131 Melbourne AUS 2865329 132 Brisbane AUS 1291117 133 Perth AUS 1096829 144 Baku AZE 1787800 +56 Luanda AGO 2022000 +69 Buenos Aires ARG 2982146 +70 La Matanza ARG 1266461 +71 Córdoba ARG 1157507 SELECT * FROM City USE INDEX () WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'L%'; ID Name Country Population @@ -752,23 +752,23 @@ id select_type table type possible_keys key key_len ref rows Extra SELECT * FROM City WHERE Name LIKE 'C%' AND Population > 1000000; ID Name Country Population -71 Córdoba ARG 1157507 -151 Chittagong BGD 1392860 -212 Curitiba BRA 1584232 -608 Cairo EGY 6789479 -712 Cape Town ZAF 2352121 -926 Conakry GIN 1090610 1026 Calcutta [Kolkata] IND 4399819 1027 Chennai (Madras) IND 3841396 +151 Chittagong BGD 1392860 1892 Chongqing CHN 6351600 1898 Chengdu CHN 3361500 1900 Changchun CHN 2812000 1910 Changsha CHN 1809800 +212 Curitiba BRA 1584232 2258 Cali COL 2077386 2485 Casablanca MAR 2940623 2515 Ciudad de México MEX 8591309 3539 Caracas VEN 1975294 3795 Chicago USA 2896016 +608 Cairo EGY 6789479 +71 Córdoba ARG 1157507 +712 Cape Town ZAF 2352121 +926 Conakry GIN 1090610 SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 1500000; ID Name Country Population @@ -918,10 +918,9 @@ ID Name Country Population 2698 Maputo MOZ 1018938 2710 Rangoon (Yangon) MMR 3361700 SELECT * FROM City -WHERE Country LIKE 'M%' AND Population > 700000; +WHERE Country LIKE 'M%' AND Population > 1000000; ID Name Country Population 2464 Kuala Lumpur MYS 1297526 -2482 Bamako MLI 809552 2485 Casablanca MAR 2940623 2515 Ciudad de México MEX 8591309 2516 Guadalajara MEX 1647720 @@ -933,17 +932,8 @@ ID Name Country Population 2522 León MEX 1133576 2523 Monterrey MEX 1108499 2524 Zapopan MEX 1002239 -2525 Naucalpan de Juárez MEX 857511 -2526 Mexicali MEX 764902 -2527 Culiacán MEX 744859 -2528 Acapulco de Juárez MEX 721011 -2529 Tlalnepantla de Baz MEX 720755 -2530 Mérida MEX 703324 -2690 Chisinau MDA 719900 -2696 Ulan Bator MNG 773700 2698 Maputo MOZ 1018938 2710 Rangoon (Yangon) MMR 3361700 -2711 Mandalay MMR 885300 SELECT * FROM City USE INDEX () WHERE Country='CHN' AND Population > 1500000; ID Name Country Population diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result index f89a68d1f8e..38e44d00215 100644 --- a/mysql-test/r/index_merge_myisam.result +++ b/mysql-test/r/index_merge_myisam.result @@ -1506,7 +1506,7 @@ index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_inter set optimizer_switch='default,index_merge_sort_union=off'; select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=on +index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=off set optimizer_switch=4; ERROR 42000: Variable 'optimizer_switch' can't be set to the value of '4' set optimizer_switch=NULL; @@ -1533,21 +1533,21 @@ set optimizer_switch=default; set optimizer_switch='index_merge=off,index_merge_union=off,default'; select @@optimizer_switch; @@optimizer_switch -index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on +index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off set optimizer_switch=default; select @@global.optimizer_switch; @@global.optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off set @@global.optimizer_switch=default; select @@global.optimizer_switch; @@global.optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off # # Check index_merge's @@optimizer_switch flags # select @@optimizer_switch; @@optimizer_switch -index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on +index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off create table t0 (a int); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t1 (a int, b int, c int, filler char(100), @@ -1657,6 +1657,6 @@ id select_type table type possible_keys key key_len ref rows Extra set optimizer_switch=default; show variables like 'optimizer_switch'; Variable_name Value -optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on +optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off drop table t0, t1; set optimizer_switch= @optimizer_switch_save; diff --git a/mysql-test/t/index_intersect.test b/mysql-test/t/index_intersect.test index d8fad05a4b0..189ea0a18a3 100644 --- a/mysql-test/t/index_intersect.test +++ b/mysql-test/t/index_intersect.test @@ -75,24 +75,24 @@ SELECT * FROM City # the previous 4 plans are valid and return # the correct results when executed - +--sorted_result SELECT * FROM City USE INDEX () WHERE Name LIKE 'C%' AND Population > 1000000; - +--sorted_result SELECT * FROM City WHERE Name LIKE 'C%' AND Population > 1000000; - +--sorted_result SELECT * FROM City USE INDEX () WHERE Name LIKE 'M%' AND Population > 1500000; - +--sorted_result SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 1500000; - +--sorted_result SELECT * FROM City USE INDEX () WHERE Name LIKE 'M%' AND Population > 300000; - +--sorted_result SELECT * FROM City WHERE Name LIKE 'M%' AND Population > 300000; @@ -223,10 +223,10 @@ SELECT * FROM City USE INDEX () SELECT * FROM City WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; - +--sorted_result SELECT * FROM City USE INDEX () WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; - +--sorted_result SELECT * FROM City WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; @@ -237,20 +237,20 @@ SELECT * FROM City USE INDEX () SELECT * FROM City WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'L%'; - +--sorted_result SELECT * FROM City USE INDEX () WHERE ID BETWEEN 3701 AND 4000 AND Population > 700000 AND Country BETWEEN 'S' AND 'Z'; - +--sorted_result SELECT * FROM City WHERE ID BETWEEN 3701 AND 4000 AND Population > 700000 AND Country BETWEEN 'S' AND 'Z'; - +--sorted_result SELECT * FROM City USE INDEX () WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 AND Country BETWEEN 'S' AND 'Z' ; - +--sorted_result SELECT * FROM City WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 AND Country BETWEEN 'S' AND 'Z' ; @@ -293,7 +293,7 @@ SELECT * FROM City #Yet the query themselves return the correct results in this case as well - +--sorted_result SELECT * FROM City WHERE Name LIKE 'C%' AND Population > 1000000; @@ -310,7 +310,7 @@ SELECT * FROM City SELECT * FROM City WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%'; - +--sorted_result SELECT * FROM City WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 AND Country BETWEEN 'S' AND 'Z'; @@ -353,17 +353,17 @@ SELECT * FROM City # Check that the previous 3 plans return the right results when executed - +--sorted_result SELECT * FROM City USE INDEX () WHERE Country LIKE 'M%' AND Population > 1000000; - +--sorted_result SELECT * FROM City - WHERE Country LIKE 'M%' AND Population > 700000; - + WHERE Country LIKE 'M%' AND Population > 1000000; +--sorted_result SELECT * FROM City USE INDEX () WHERE Country='CHN' AND Population > 1500000; - +--sorted_result SELECT * FROM City WHERE Country='CHN' AND Population > 1500000; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index f332aee0457..9a8016fed02 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -559,14 +559,12 @@ protected: # define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \ OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \ OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \ - OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \ - OPTIMIZER_SWITCH_INDEX_MERGE_SORT_INTERSECT) + OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT) #else # define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \ OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \ OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \ OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \ - OPTIMIZER_SWITCH_INDEX_MERGE_SORT_INTERSECT | \ OPTIMIZER_SWITCH_TABLE_ELIMINATION) #endif diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9d662ea0174..4d6007f0bb8 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -433,7 +433,7 @@ static const char *sql_mode_str= "OFF"; static const char *optimizer_switch_str="index_merge=on,index_merge_union=on," "index_merge_sort_union=on," "index_merge_intersection=on," - "index_merge_sort_intersection=on" + "index_merge_sort_intersection=off" #ifndef DBUG_OFF ",table_elimination=on"; #else diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 05c15f864db..3ff670d045c 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -4863,6 +4863,17 @@ ha_rows records_in_index_intersect_extension(PARTIAL_INDEX_INTERSECT_INFO *curr, when searching for the best intersection plan. It also allocates memory to store the most cheap index intersection. + NOTES + When selecting candidates for index intersection we always take only + one representative out of any set of indexes that share the same range + conditions. These indexes always have the same prefixes and the + components of this prefixes are exactly those used in these range + conditions. + Range conditions over clustered primary key (cpk) is always used only + as the condition that filters out some rowids retrieved by the scans + for secondary indexes. The cpk index will be handled in special way by + the function that search for the best index intersection. + RETURN FALSE in the case of success TRUE otherwise @@ -4935,7 +4946,7 @@ bool prepare_search_best_index_intersect(PARAM *param, if (*index_scan == cpk_scan) continue; - if (cpk_scan && cpk_scan->used_key_parts == used_key_parts && + if (cpk_scan && cpk_scan->used_key_parts >= used_key_parts && same_index_prefix(cpk_scan->key_info, key_info, used_key_parts)) continue; @@ -5012,7 +5023,7 @@ bool prepare_search_best_index_intersect(PARAM *param, curr.intersect_fields= &cpk_scan->used_fields; curr.records= cpk_scan->records; curr.length= 1; - for (scan_ptr=selected_index_scans, i= 0; *scan_ptr; scan_ptr++, i++) + for (scan_ptr=selected_index_scans; *scan_ptr; scan_ptr++) { ha_rows scan_records= (*scan_ptr)->records; ha_rows records= records_in_index_intersect_extension(&curr, *scan_ptr); @@ -5022,7 +5033,7 @@ bool prepare_search_best_index_intersect(PARAM *param, } else { - for (scan_ptr=selected_index_scans, i= 0; *scan_ptr; scan_ptr++, i++) + for (scan_ptr=selected_index_scans; *scan_ptr; scan_ptr++) (*scan_ptr)->filtered_out= 0; } @@ -5250,6 +5261,13 @@ ha_rows records_in_index_intersect_extension(PARTIAL_INDEX_INTERSECT_INFO *curr, } +/* + Estimate the cost a binary search within disjoint cpk range intervals + + Number of comparisons to check whether a cpk value satisfies + the cpk range condition = log2(cpk_scan->range_count). +*/ + static inline double get_cpk_filter_cost(ha_rows filtered_records, INDEX_SCAN_INFO *cpk_scan, @@ -5412,6 +5430,7 @@ void find_index_intersect_best_extension(PARTIAL_INDEX_INTERSECT_INFO *curr) common_info->best_length= curr->length; common_info->best_records= curr->records; common_info->filtered_scans= curr->filtered_scans; + /* common_info->best_uses_cpk <=> at least one scan uses a cpk filter */ common_info->best_uses_cpk= !curr->filtered_scans.is_clear_all(); uint sz= sizeof(INDEX_SCAN_INFO *) * curr->length; memcpy(common_info->best_intersect, common_info->search_scans, sz); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 288369eedba..d00455c8abb 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6376,8 +6376,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) if (tab->type == JT_REF && tab->quick && (((uint) tab->ref.key == tab->quick->index && tab->ref.key_length < tab->quick->max_used_key_length) || - (!tab->table->intersect_keys.is_clear_all() && - tab->table->intersect_keys.is_set(tab->ref.key)))) + tab->table->intersect_keys.is_set(tab->ref.key))) { /* Range uses longer key; Use this instead of ref on key */ tab->type=JT_ALL;