2016-08-29 1 views
1

Я пытаюсь присоединиться к файлу, который является int (13), для поля, которое является varchar (50).как преобразовать поле в строку в соединении mysql

Если я использую только (a.id = b.id), то DESCRIBE говорит: тип.

Если я использую (a.id = CONCAT(b.id)), DESCRIBE говорит тип: eq_ref. (где b.id является целым числом)

Использование CONCAT, чтобы отличить поле, является уродливым, поэтому я попытался использовать CAST() или CONVERT().

Если я использую (a.id = CAST(b.id AS CHAR(50))), то DESCRIBE говорит тип: ref.

Как написать правильное преобразование/преобразование, которое дает соединение eq_ref?

UPDATE 1:

ОПИСАТЬ ВЫБРАТЬ .. с CONCAT

+------+-------------+-----------------------+--------+-----------------------------------+----------------+---------+-------------------------------------+------+----------------------------------------+ 
| id | select_type | table     | type | possible_keys      | key   | key_len | ref         | rows | Extra         | 
+------+-------------+-----------------------+--------+-----------------------------------+----------------+---------+-------------------------------------+------+----------------------------------------+ 
| 1 | SIMPLE  | ext_icecat_prodmatch | ref | PRIMARY,our_article_id,product_id | our_article_id | 152  | const        | 3016 | Using index condition; Using temporary | 
| 1 | SIMPLE  | ext_icecat_product | eq_ref | PRIMARY,product_id    | PRIMARY  | 4  | ext_icecat_prodmatch.product_id  | 1 |          | 
| 1 | SIMPLE  | ext_icecat_supplier | eq_ref | PRIMARY       | PRIMARY  | 4  | ext_icecat_product.supplier_id  | 1 |          | 
| 1 | SIMPLE  | products    | eq_ref | PRIMARY       | PRIMARY  | 152  | ext_icecat_prodmatch.our_article_id | 1 |          | 
| 1 | SIMPLE  | partner_product_saved | eq_ref | PRIMARY       | PRIMARY  | 155  | const,func       | 1 | Using where       | 
| 1 | SIMPLE  | category_names  | eq_ref | PRIMARY       | PRIMARY  | 6  | products.category_id,const   | 1 | Using where       | 
+------+-------------+-----------------------+--------+-----------------------------------+----------------+---------+-------------------------------------+------+----------------------------------------+ 

The Select:

SELECT 
    partner_product_saved.*, 
    ext_icecat_product.product_id, 
    CONCAT(ext_icecat_supplier.name, ' ', ext_icecat_product.name) AS export_product_name, 
    ext_icecat_product.catid_match AS category_id, 
    GROUP_CONCAT(ext_icecat_prodmatch.our_article_id) AS oais, 
    products.file_name, 
    category_names.category_path 
FROM ext_icecat_product 
    LEFT JOIN ext_icecat_prodmatch USING (product_id) 
    LEFT JOIN ext_icecat_supplier USING (supplier_id) 
    LEFT JOIN products USING (our_article_id) 
    LEFT JOIN partner_product_saved ON (partner_product_saved.partner_id = 29 AND partner_product_saved.product_id = CONCAT(ext_icecat_product.product_id)) 
    LEFT JOIN category_names ON (category_names.category_id = products.category_id AND category_names.language_id = 2) 
WHERE ext_icecat_prodmatch.our_article_id = '0EF03850-D25A-1174-BCDC-EC67352010A6' 
GROUP BY ext_icecat_product.product_id 
ORDER BY NULL; 

SHOW CREATE TABLE

CREATE TABLE `partner_product_saved` (
    `partner_id` mediumint(8) NOT NULL, 
    `product_id` varchar(50) CHARACTER SET utf8 NOT NULL, 
    `product_name` varchar(100) CHARACTER SET utf8 NOT NULL, 
    `our_article_id` varchar(50) CHARACTER SET utf8 DEFAULT NULL, 
    `our_category_id` mediumint(8) DEFAULT NULL, 
    `manufacture_id` mediumint(8) DEFAULT NULL, 
    `manufacturer_partnr` varchar(255) COLLATE utf8_bin NOT NULL, 
    `manufacturer_upc` varchar(255) COLLATE utf8_bin NOT NULL, 
    `image` tinytext COLLATE utf8_bin NOT NULL, 
    `image_small` tinytext COLLATE utf8_bin NOT NULL, 
    `image_big` tinytext COLLATE utf8_bin NOT NULL, 
    `image_200` tinytext COLLATE utf8_bin NOT NULL, 
    `image_original` tinytext COLLATE utf8_bin NOT NULL, 
    `image_width` int(11) DEFAULT NULL, 
    `image_height` int(11) DEFAULT NULL, 
    `birth` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `last_updated` timestamp NULL DEFAULT NULL, 
    `saved` tinyint(3) unsigned NOT NULL DEFAULT '0', 
    PRIMARY KEY (`partner_id`,`product_id`), 
    KEY `our_article_id` (`our_article_id`), 
    KEY `our_category_id` (`our_category_id`), 
    KEY `manufacture_id` (`manufacture_id`,`manufacturer_partnr`), 
    KEY `manufacturer_upc` (`manufacturer_upc`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 

CREATE TABLE `ext_icecat_product` (
    `product_id` int(13) NOT NULL, 
    `supplier_id` int(13) NOT NULL DEFAULT '0', 
    `prod_id` varchar(235) COLLATE utf8_bin NOT NULL DEFAULT '', 
    `prod_id_clean` varchar(255) CHARACTER SET utf8 NOT NULL, 
    `catid` int(13) NOT NULL DEFAULT '0', 
    `catid_match` varchar(50) CHARACTER SET utf8 NOT NULL, 
    `name` varchar(255) CHARACTER SET utf8 NOT NULL, 
    `name_clean` varchar(255) CHARACTER SET utf8 NOT NULL, 
    `low_pic` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '', 
    `high_pic` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '', 
    `thumb_pic` varchar(255) COLLATE utf8_bin DEFAULT NULL, 
    `family_id` int(13) NOT NULL DEFAULT '0', 
    `low_pic_size` int(13) DEFAULT '0', 
    `high_pic_size` int(13) DEFAULT '0', 
    `thumb_pic_size` int(13) DEFAULT '0', 
    `import_date` datetime NOT NULL, 
    `release_date` datetime NOT NULL, 
    `updated` datetime NOT NULL, 
    `need_update` tinyint(1) NOT NULL DEFAULT '0', 
    `deleted` tinyint(1) NOT NULL DEFAULT '0', 
    `keyword` tinyint(1) NOT NULL DEFAULT '0', 
    `special_match` tinyint(1) NOT NULL DEFAULT '0', 
    PRIMARY KEY (`product_id`), 
    KEY `supplier_id` (`supplier_id`), 
    KEY `catid` (`catid`), 
    KEY `prod_id` (`prod_id`), 
    KEY `product_id` (`product_id`,`prod_id`,`supplier_id`), 
    KEY `release_Date` (`release_date`), 
    KEY `prod_id_clean` (`prod_id_clean`), 
    KEY `name_clean` (`name_clean`), 
    KEY `need_update` (`need_update`), 
    KEY `deleted` (`deleted`), 
    KEY `keyword` (`keyword`), 
    KEY `catid_2` (`catid`,`import_date`), 
    KEY `catid_match` (`catid_match`), 
    KEY `special_match` (`special_match`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 
+1

В чем проблема с использованием '(a.id = b.id)'? – trincot

+0

Мое предположение о его преобразовании VARCHAR в INT, и поэтому не может использовать индекс –

+1

Вы провели сравнение (a.id = b.id) v (a.id = CONCAT (b.id))? – Jaydee

ответ

-1

WHERE indexed_column = any_function(any_column) - может нам e index. WHERE non_indexed_column = any_function(indexed_column) - Нельзя использовать индекс.

Разница между ref и eq_ref незначительна. Я думаю, что eq_ref - это то, где оптимизатор решает, что не может быть более одного совпадения, часто из-за UNIQUE.

WHERE ext_icecat_prodmatch.our_article_id = '0EF03850-D25A-1174-BCDC-EC67352010A6' - есть our_article_idINDEXed? или UNIQUE? Похоже, что это всего лишь INDEX, поэтому может появиться несколько строк. Чтобы сделать это eq_ref, вам нужно UNIQUE. Но только если данные поддерживают такие. Статистика подразумевает, что с этой статьей_id может быть 3016 строк.

Не используйте LEFT, если это не нужно. Обратите внимание, как Оптимизатор повернул LEFT JOIN ext_icecat_prodmatch USING (product_id) в JOIN и решил (правильно) начать с ext_icecat_prodmatch.

Назад к другим дискуссии ...

AND partner_product_saved.product_id = CONCAT(ext_icecat_product.product_id)) 

может идти в одну сторону, а не другой. То есть, он может эффективно перейти от eip к pps, но не в другую сторону. И EXPLAIN обозначены такими const,func.

+0

«is our_article_id INDEXed?», Если вы читаете объяснение, эта строка является «ref» и имеет 3016rows, используя ключ our_article_id, так что да, это индекс, а не часть проблемы. Использование «LEFT JOIN» в основном просто ленив, так как я использую 'implode (« LEFT JOIN », $ tables)' для создания запроса, но optiomer всегда решает это правильно. –

+0

«может идти в одну сторону, но не в другую». Да, так же, как 'AND partner_product_saved.product_id = CAST (ext_icecat_product.product_id) AS CHAR)' –

Смежные вопросы