워드프레스가 무거운 것은 Mysql 테이블 스키마가 무겁고, 하나의 화면을 구성하기 위해 include 해야하는 파일이 많아서 입니다.
이런 상황에서 빠른 속도를 연출하려면, mysql 테이블 스키마를 바꾸고, 하나의 화면을 보여주기 위해 include 하는 과정을 cache 를 통해 줄여야 합니다.
저희가 운영하는 http://lyric.nett.kr 서비스의 경우 wp_posts 컨텐츠에 수십만개의 컨텐츠를 등록하여 활용하고 있는데요.
테이블 스키마를 보여드리겠습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
CREATE TABLE `wp_posts` ( `ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `post_author` bigint(20) unsigned NOT NULL DEFAULT '0', `post_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `post_date_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `post_content` text NOT NULL, `post_title` varchar(400) NOT NULL, `post_excerpt` char(1) NOT NULL, `post_status` varchar(20) NOT NULL DEFAULT 'publish', `comment_status` varchar(20) NOT NULL DEFAULT 'open', `ping_status` varchar(20) NOT NULL DEFAULT 'open', `post_password` char(1) NOT NULL, `post_name` varchar(200) NOT NULL DEFAULT '', `to_ping` char(1) NOT NULL, `pinged` char(1) NOT NULL, `post_modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `post_modified_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `post_content_filtered` char(1) NOT NULL, `post_parent` bigint(20) unsigned NOT NULL DEFAULT '0', `guid` varchar(255) NOT NULL DEFAULT '', `menu_order` int(11) NOT NULL DEFAULT '0', `post_type` varchar(20) NOT NULL DEFAULT 'post', `post_mime_type` varchar(100) NOT NULL DEFAULT '', `comment_count` bigint(20) NOT NULL DEFAULT '0', PRIMARY KEY (`ID`), KEY `post_name` (`post_name`(191)), KEY `type_status_date` (`post_type`,`post_status`,`post_date`,`ID`), KEY `post_parent` (`post_parent`), KEY `post_author` (`post_author`), KEY `post_modified_gmt` (`post_modified_gmt`), KEY `post_date` (`post_date`), KEY `type_status_date_gmt` (`post_type`,`post_status`,`post_date_gmt`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 /*!50100 PARTITION BY RANGE (ID) (PARTITION p01 VALUES LESS THAN (50000) ENGINE = InnoDB, PARTITION p02 VALUES LESS THAN (100000) ENGINE = InnoDB, PARTITION p03 VALUES LESS THAN (150000) ENGINE = InnoDB, PARTITION p04 VALUES LESS THAN (200000) ENGINE = InnoDB, PARTITION p05 VALUES LESS THAN (250000) ENGINE = InnoDB, PARTITION p06 VALUES LESS THAN (300000) ENGINE = InnoDB, PARTITION p07 VALUES LESS THAN (350000) ENGINE = InnoDB, PARTITION p08 VALUES LESS THAN (400000) ENGINE = InnoDB, PARTITION p09 VALUES LESS THAN (450000) ENGINE = InnoDB, PARTITION p10 VALUES LESS THAN (500000) ENGINE = InnoDB, PARTITION p11 VALUES LESS THAN (550000) ENGINE = InnoDB, PARTITION p12 VALUES LESS THAN (600000) ENGINE = InnoDB, PARTITION p13 VALUES LESS THAN (650000) ENGINE = InnoDB, PARTITION p14 VALUES LESS THAN (700000) ENGINE = InnoDB, PARTITION p15 VALUES LESS THAN (750000) ENGINE = InnoDB, PARTITION p16 VALUES LESS THAN (800000) ENGINE = InnoDB, PARTITION p17 VALUES LESS THAN (850000) ENGINE = InnoDB, PARTITION p18 VALUES LESS THAN (900000) ENGINE = InnoDB, PARTITION p19 VALUES LESS THAN (950000) ENGINE = InnoDB, PARTITION p20 VALUES LESS THAN (1000000) ENGINE = InnoDB) */; CREATE TABLE `wp_postmeta` ( `meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `post_id` bigint(20) unsigned NOT NULL DEFAULT '0', `meta_key` varchar(255) DEFAULT NULL, `meta_value` text, PRIMARY KEY (`meta_id`), KEY `post_id` (`post_id`), KEY `meta_key` (`meta_key`(191)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 /*!50100 PARTITION BY RANGE (meta_id) (PARTITION p01 VALUES LESS THAN (50000) ENGINE = InnoDB, PARTITION p02 VALUES LESS THAN (100000) ENGINE = InnoDB, PARTITION p03 VALUES LESS THAN (150000) ENGINE = InnoDB, PARTITION p04 VALUES LESS THAN (200000) ENGINE = InnoDB, PARTITION p05 VALUES LESS THAN (250000) ENGINE = InnoDB, PARTITION p06 VALUES LESS THAN (300000) ENGINE = InnoDB, PARTITION p07 VALUES LESS THAN (350000) ENGINE = InnoDB, PARTITION p08 VALUES LESS THAN (400000) ENGINE = InnoDB, PARTITION p09 VALUES LESS THAN (450000) ENGINE = InnoDB, PARTITION p10 VALUES LESS THAN (500000) ENGINE = InnoDB, PARTITION p11 VALUES LESS THAN (550000) ENGINE = InnoDB, PARTITION p12 VALUES LESS THAN (600000) ENGINE = InnoDB, PARTITION p13 VALUES LESS THAN (650000) ENGINE = InnoDB, PARTITION p14 VALUES LESS THAN (700000) ENGINE = InnoDB, PARTITION p15 VALUES LESS THAN (750000) ENGINE = InnoDB, PARTITION p16 VALUES LESS THAN (800000) ENGINE = InnoDB, PARTITION p17 VALUES LESS THAN (850000) ENGINE = InnoDB, PARTITION p18 VALUES LESS THAN (900000) ENGINE = InnoDB, PARTITION p19 VALUES LESS THAN (950000) ENGINE = InnoDB, PARTITION p20 VALUES LESS THAN (1000000) ENGINE = InnoDB, PARTITION p21 VALUES LESS THAN (1050000) ENGINE = InnoDB, PARTITION p22 VALUES LESS THAN (1100000) ENGINE = InnoDB, PARTITION p23 VALUES LESS THAN (1150000) ENGINE = InnoDB, PARTITION p24 VALUES LESS THAN (1200000) ENGINE = InnoDB, PARTITION p25 VALUES LESS THAN (1250000) ENGINE = InnoDB, PARTITION p26 VALUES LESS THAN (1300000) ENGINE = InnoDB, PARTITION p27 VALUES LESS THAN (1350000) ENGINE = InnoDB, PARTITION p28 VALUES LESS THAN (1400000) ENGINE = InnoDB, PARTITION p29 VALUES LESS THAN (1450000) ENGINE = InnoDB, PARTITION p30 VALUES LESS THAN (1500000) ENGINE = InnoDB, PARTITION p31 VALUES LESS THAN (1550000) ENGINE = InnoDB, PARTITION p32 VALUES LESS THAN (1600000) ENGINE = InnoDB, PARTITION p33 VALUES LESS THAN (1650000) ENGINE = InnoDB, PARTITION p34 VALUES LESS THAN (1700000) ENGINE = InnoDB, PARTITION p35 VALUES LESS THAN (1750000) ENGINE = InnoDB, PARTITION p36 VALUES LESS THAN (1800000) ENGINE = InnoDB, PARTITION p37 VALUES LESS THAN (1850000) ENGINE = InnoDB, PARTITION p38 VALUES LESS THAN (1900000) ENGINE = InnoDB, PARTITION p39 VALUES LESS THAN (1950000) ENGINE = InnoDB, PARTITION p40 VALUES LESS THAN (2000000) ENGINE = InnoDB, PARTITION p41 VALUES LESS THAN (2050000) ENGINE = InnoDB, PARTITION p42 VALUES LESS THAN (2100000) ENGINE = InnoDB, PARTITION p43 VALUES LESS THAN (2150000) ENGINE = InnoDB, PARTITION p44 VALUES LESS THAN (2200000) ENGINE = InnoDB, PARTITION p45 VALUES LESS THAN (2250000) ENGINE = InnoDB, PARTITION p46 VALUES LESS THAN (2300000) ENGINE = InnoDB, PARTITION p47 VALUES LESS THAN (2350000) ENGINE = InnoDB, PARTITION p48 VALUES LESS THAN (2400000) ENGINE = InnoDB, PARTITION p49 VALUES LESS THAN (2450000) ENGINE = InnoDB, PARTITION p50 VALUES LESS THAN (2500000) ENGINE = InnoDB, PARTITION p51 VALUES LESS THAN (2550000) ENGINE = InnoDB, PARTITION p52 VALUES LESS THAN (2600000) ENGINE = InnoDB, PARTITION p53 VALUES LESS THAN (2650000) ENGINE = InnoDB, PARTITION p54 VALUES LESS THAN (2700000) ENGINE = InnoDB, PARTITION p55 VALUES LESS THAN (2750000) ENGINE = InnoDB, PARTITION p56 VALUES LESS THAN (2800000) ENGINE = InnoDB, PARTITION p57 VALUES LESS THAN (2850000) ENGINE = InnoDB, PARTITION p58 VALUES LESS THAN (2900000) ENGINE = InnoDB, PARTITION p59 VALUES LESS THAN (2950000) ENGINE = InnoDB, PARTITION p60 VALUES LESS THAN (3000000) ENGINE = InnoDB, PARTITION p61 VALUES LESS THAN (3050000) ENGINE = InnoDB, PARTITION p62 VALUES LESS THAN (3100000) ENGINE = InnoDB, PARTITION p63 VALUES LESS THAN (3150000) ENGINE = InnoDB, PARTITION p64 VALUES LESS THAN (3200000) ENGINE = InnoDB, PARTITION p65 VALUES LESS THAN (3250000) ENGINE = InnoDB, PARTITION p66 VALUES LESS THAN (3300000) ENGINE = InnoDB, PARTITION p67 VALUES LESS THAN (3350000) ENGINE = InnoDB, PARTITION p68 VALUES LESS THAN (3400000) ENGINE = InnoDB, PARTITION p69 VALUES LESS THAN (3450000) ENGINE = InnoDB, PARTITION p70 VALUES LESS THAN (3500000) ENGINE = InnoDB, PARTITION p71 VALUES LESS THAN (3550000) ENGINE = InnoDB, PARTITION p72 VALUES LESS THAN (3600000) ENGINE = InnoDB, PARTITION p73 VALUES LESS THAN (3650000) ENGINE = InnoDB, PARTITION p74 VALUES LESS THAN (3700000) ENGINE = InnoDB, PARTITION p75 VALUES LESS THAN (3750000) ENGINE = InnoDB, PARTITION p76 VALUES LESS THAN (3800000) ENGINE = InnoDB, PARTITION p77 VALUES LESS THAN (3850000) ENGINE = InnoDB, PARTITION p78 VALUES LESS THAN (3900000) ENGINE = InnoDB, PARTITION p79 VALUES LESS THAN (3950000) ENGINE = InnoDB, PARTITION p80 VALUES LESS THAN (4000000) ENGINE = InnoDB) */; |
자, 위의 테이블 스키마가 어떤 부분이 달라졌는지 일반적인 스키마와 비교해볼까요 ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
CREATE TABLE `wp_posts` ( `ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `post_author` bigint(20) unsigned NOT NULL DEFAULT '0', `post_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `post_date_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `post_content` longtext COLLATE utf8mb4_unicode_520_ci NOT NULL, `post_title` text COLLATE utf8mb4_unicode_520_ci NOT NULL, `post_excerpt` text COLLATE utf8mb4_unicode_520_ci NOT NULL, `post_status` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'publish', `comment_status` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'open', `ping_status` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'open', `post_password` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', `post_name` varchar(200) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', `to_ping` text COLLATE utf8mb4_unicode_520_ci NOT NULL, `pinged` text COLLATE utf8mb4_unicode_520_ci NOT NULL, `post_modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `post_modified_gmt` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', `post_content_filtered` longtext COLLATE utf8mb4_unicode_520_ci NOT NULL, `post_parent` bigint(20) unsigned NOT NULL DEFAULT '0', `guid` varchar(255) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', `menu_order` int(11) NOT NULL DEFAULT '0', `post_type` varchar(20) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT 'post', `post_mime_type` varchar(100) COLLATE utf8mb4_unicode_520_ci NOT NULL DEFAULT '', `comment_count` bigint(20) NOT NULL DEFAULT '0', PRIMARY KEY (`ID`), KEY `post_name` (`post_name`(191)), KEY `type_status_date` (`post_type`,`post_status`,`post_date`,`ID`), KEY `post_parent` (`post_parent`), KEY `post_author` (`post_author`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; CREATE TABLE `wp_postmeta` ( `meta_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `post_id` bigint(20) unsigned NOT NULL DEFAULT '0', `meta_key` varchar(255) COLLATE utf8mb4_unicode_520_ci DEFAULT NULL, `meta_value` longtext COLLATE utf8mb4_unicode_520_ci, PRIMARY KEY (`meta_id`), KEY `post_id` (`post_id`), KEY `meta_key` (`meta_key`(191)) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci; |
위의 예시는 cafe24 에서 자동으로 설치해주는 워드프레스 스키마입니다.
우선 컨텐츠가 100,000 개 이상이 되면 워드프레스의 기본적인 스키마를 사용하게 되면 너무나 느려지게 됩니다.
text 와 longtext 는 차이가 크기 때문에, 중요한 다이어트 포인트가 됩니다.
post_content
longtext COLLATE utf8mb4_unicode_520_ci NOT NULL,
post_title
text COLLATE utf8mb4_unicode_520_ci NOT NULL,
post_excerpt
text COLLATE utf8mb4_unicode_520_ci NOT NULL,
post_content
text NOT NULL,
post_title
varchar(400) NOT NULL,
post_excerpt
char(1) NOT NULL,
post_excerpt 를 사용하지 않아서 char(1) 로 바꾸어 보았습니다.
테이블 스키마를 실제 사용하는 환경에 맞추어 적절하게 바꾸면, 큰 성능 향상을 경험하게 될 것 입니다.
파티셔닝 partitioning 은 굉장히 중요한 작업이고요.
워드프레스는 단순히 그것을 사용하는 사람들에게 기초적인 틀을 제공해주며, 워드프레스를 사용해서 더 불편하거나 손해보는 상황이 되지는 않습니다.
단지, 워드프레스를 제대로 이해하지 못한 상태에서 성능이 느리다느니 불평을 하면, 테이블 스키마를 고쳐볼 생각을 왜 하지 않는지 물어 보고 싶더라고요.
어떤 프로그램이던 워드프레스로 컨버팅하면 테마와 플러그인으로 부터 받는 엄청난 혜택이 있어서, 오래된 서비스를 워드프레스로 컨버팅하는 일들이 꼭 필요하고 중요한 일이다라고 말씀드리고 싶답니다.
기존 서비스가 막코딩으로 개발했는데 워드프레스로 래핑하고 기능을 살릴 수 있나요 ? 라면..
당연히 가능합니다.
기존 서비스의 구성들을 워드프레스의 구성에 맞게 재설계하고 단단한 프레임웍 위에 플러그인으로 분리하여 서비스를 구성하면 되니깐요.
$wpdb, $wp_query 라는 존재만 제대로 이해하면 누구나 워드프레스를 지금 보다 더 자유롭게 활용할 수 있을 거에요.