0

우리는 고객을 위해 웹 사이트를 관리합니다.이 웹 사이트는 심각한 성능 문제를 다루고 있습니다. 이 웹 사이트는 CMS 내에 구축되며 최대 20 명의 방문자를 동시에 처리합니다. 웹 사이트의 방문자가 사이트의 유일한 사용자 인 한 모든 것이 잘됩니다. CMS는 캐시를 만들고 mysql 쿼리의 사용은 최소한으로 유지됩니다.성능 문제 mysql 데이터베이스

고객의 직원이 사이트에서 직접 작업을 시작하면 성능이 저하되기 시작합니다. 전체 워크 플로우는 사이트를 거쳐 데이터베이스의 레코드를 업데이트하고 새로운 레코드를 삽입하는 작업을 포함합니다. 레코드가 업데이트되면 삭제되거나 삽입 된 캐시가 삭제되어 웹 사이트의 방문자가 수행 한 작업이 쿼리로 넘어갑니다.

내 첫 번째 질문은 mysql이 이러한 요청을 처리 할 수 ​​있어야 하는가? 데이터베이스의 디자인이 좋지 않더라도 (아래 참조). mysql에서 processlist를 볼 때 간단한 쿼리가 최대 15 초가 걸리는 것을 볼 수 있습니다. 이러한 쿼리는 업데이트 또는 삽입 쿼리가 동시에 진행될 때만 너무 오래 걸리는 것처럼 보입니다.

모든 레코드를 보유하고있는 큰 테이블 아래. 웹 사이트 프론트 엔드에서 사용하는 모든 것이이 테이블에 저장됩니다. 이진 파일을 포함하는 이 테이블에는 총 8,676 개의 레코드가 있습니다. 프론트 엔드에는 WHERE를 사용하는 많은 쿼리가 있습니다. 예를 들어 Variabele5 또는 Variabele6 이 Variabele 필드의 값은 contenttype에 따라 다릅니다. 예를 들어입니다

:

WHERE Variabele5 > 500 AND Variabele6 =2 AND contenttype = 35 

모든 직원이 캐시되지 않습니다 작동 환경. 이 환경에는 주문 및 검색 옵션이있는 몇 가지 목록이 있습니다. 이러한 쿼리는 가능한 한 많이 memcached되지만 레코드가 업데이트되거나 삭제되거나 삽입되면 memcache가 지워집니다. 삽입, 업데이트 및 삭제 작업과 함께 병목 현상이 발생할 수 있습니다.

제 질문은이 모든 것을 처리 할 수 ​​있어야하거나 요청을 처리하기에 좋지 않은 데이터베이스 설계입니다.

 
+---------------+---------------+------+-----+---------+----------------+ 
|  Field  |  Type  | Null | Key | Default |  Extra  | 
+---------------+---------------+------+-----+---------+----------------+ 
| nr   | mediumint(80) | NO | PRI | NULL | auto_increment | 
| hidden  | int(1)  | NO |  | 0  |    | 
| Title   | varchar(255) | NO | MUL |   |    | 
| Body   | text   | NO |  | NULL |    | 
| Description | text   | NO |  | NULL |    | 
| user_id  | mediumint(80) | NO |  | 0  |    | 
| addate  | varchar(255) | NO |  | NULL |    | 
| moddate  | varchar(255) | NO |  | NULL |    | 
| contenttype | mediumint(80) | NO | MUL | 0  |    | 
| parent  | mediumint(80) | NO |  | 0  |    | 
| Status  | mediumint(80) | NO | MUL | NULL |    | 
| CODE   | varchar(255) | NO | MUL | NULL |    | 
| menu   | mediumint(80) | NO |  | NULL |    | 
| filetype  | mediumint(80) | NO |  | NULL |    | 
| folder  | int(11)  | NO |  | NULL |    | 
| sortIndex  | bigint(255) | NO |  | NULL |    | 
| servercache | int(1)  | NO |  | 1  |    | 
| futurecache | int(1)  | NO |  | NULL |    | 
| publishFrom | date   | YES |  | NULL |    | 
| publishUntil | date   | YES |  | NULL |    | 
| pinned  | int(11)  | YES |  | NULL |    | 
| keywords  | text   | NO |  | NULL |    | 
| latestversion | int(11)  | NO |  | NULL |    | 
| permalink  | text   | NO |  | NULL |    | 
| Integer1  | int(12)  | NO |  | 0  |    | 
| Integer2  | int(4)  | NO |  | 0  |    | 
| Integer3  | int(4)  | NO |  | 0  |    | 
| Integer4  | int(4)  | NO |  | 0  |    | 
| Variabele1 | varchar(255) | NO |  |   |    | 
| Variabele2 | varchar(255) | NO |  |   |    | 
| Variabele3 | varchar(255) | NO |  |   |    | 
| Variabele4 | varchar(255) | NO |  |   |    | 
| Date1   | varchar(255) | NO |  |   |    | 
| Date2   | varchar(255) | NO |  |   |    | 
| Text1   | text   | NO |  | NULL |    | 
| Text2   | text   | NO |  | NULL |    | 
| Text3   | text   | NO |  | NULL |    | 
| Binary1  | longblob  | NO |  | NULL |    | 
| Binary1Type | varchar(255) | NO |  | NULL |    | 
| Binary2  | longblob  | NO |  | NULL |    | 
| Binary2Type | varchar(255) | NO |  | NULL |    | 
| Binary3  | longblob  | NO |  | NULL |    | 
| Binary3Type | varchar(255) | NO |  | NULL |    | 
| browseAccess | varchar(255) | NO |  | NULL |    | 
| Binary4  | longblob  | NO |  | NULL |    | 
| Binary4Type | varchar(255) | NO |  | NULL |    | 
| Binary5  | longblob  | NO |  | NULL |    | 
| Binary5Type | varchar(255) | NO |  | NULL |    | 
| Binary6  | longblob  | NO |  | NULL |    | 
| Binary6Type | varchar(255) | NO |  | NULL |    | 
| Integer5  | int(11)  | NO |  | NULL |    | 
| Integer6  | int(11)  | NO |  | NULL |    | 
| Variabele6 | varchar(255) | NO |  | NULL |    | 
| Binary7  | longblob  | NO |  | NULL |    | 
| Binary7Type | varchar(255) | NO |  | NULL |    | 
| Binary8  | longblob  | NO |  | NULL |    | 
| Binary8Type | varchar(255) | NO |  | NULL |    | 
| Binary9  | longblob  | NO |  | NULL |    | 
| Binary9Type | varchar(255) | NO |  | NULL |    | 
| Binary10  | longblob  | NO |  | NULL |    | 
| Binary10Type | varchar(255) | NO |  | NULL |    | 
| Binary11  | longblob  | NO |  | NULL |    | 
| Binary11Type | varchar(255) | NO |  | NULL |    | 
| Binary12  | longblob  | NO |  | NULL |    | 
| Binary12Type | varchar(255) | NO |  | NULL |    | 
| Binary13  | longblob  | NO |  | NULL |    | 
| Binary13Type | varchar(255) | NO |  | NULL |    | 
| Binary14  | longblob  | NO |  | NULL |    | 
| Binary14Type | varchar(255) | NO |  | NULL |    | 
| Binary15  | longblob  | NO |  | NULL |    | 
| Binary15Type | varchar(255) | NO |  | NULL |    | 
| Text4   | text   | NO |  | NULL |    | 
| Text5   | text   | NO |  | NULL |    | 
| Text6   | text   | NO |  | NULL |    | 
| Text7   | text   | NO |  | NULL |    | 
| Text8   | text   | NO |  | NULL |    | 
| Variabele5 | varchar(255) | NO |  | NULL |    | 
| Variabele7 | varchar(255) | NO |  | NULL |    | 
| Variabele8 | varchar(255) | NO |  | NULL |    | 
| Variabele9 | varchar(255) | NO |  | NULL |    | 
| Variabele10 | text   | NO |  | NULL |    | 
| Variabele11 | varchar(255) | NO |  | NULL |    | 
| Variabele12 | varchar(255) | NO |  | NULL |    | 
| Variabele13 | varchar(255) | NO |  | NULL |    | 
| Variabele14 | varchar(255) | NO |  | NULL |    | 
| Variabele15 | varchar(255) | NO |  | NULL |    | 
| Variabele16 | varchar(255) | NO |  | NULL |    | 
| Variabele17 | varchar(255) | NO |  | NULL |    | 
| Variabele18 | varchar(255) | NO |  | NULL |    | 
| Variabele19 | varchar(255) | NO |  | NULL |    | 
| Variabele20 | varchar(255) | NO |  | NULL |    | 
| Variabele21 | varchar(255) | NO |  | NULL |    | 
| Variabele22 | varchar(255) | NO |  | NULL |    | 
| Variabele23 | varchar(255) | NO |  | NULL |    | 
| Variabele24 | varchar(255) | NO |  | NULL |    | 
| Variabele25 | varchar(255) | NO |  | NULL |    | 
| Variabele26 | varchar(255) | NO |  | NULL |    | 
| Variabele27 | varchar(255) | NO |  | NULL |    | 
| Variabele28 | varchar(255) | NO |  | NULL |    | 
| Variabele29 | varchar(255) | NO |  | NULL |    | 
| Variabele30 | varchar(255) | NO |  | NULL |    | 
| Variabele31 | varchar(255) | NO |  | NULL |    | 
| Variabele32 | varchar(255) | NO |  | NULL |    | 
| Variabele33 | varchar(255) | NO |  | NULL |    | 
| Variabele34 | varchar(255) | NO |  | NULL |    | 
| Variabele35 | varchar(255) | NO |  | NULL |    | 
| Variabele36 | varchar(255) | NO |  | NULL |    | 
| Variabele37 | varchar(255) | NO |  | NULL |    | 
| Variabele38 | varchar(255) | NO |  | NULL |    | 
| Variabele39 | varchar(255) | NO |  | NULL |    | 
| Variabele40 | varchar(255) | NO |  | NULL |    | 
| Variabele41 | varchar(255) | NO |  | NULL |    | 
| Variabele42 | varchar(255) | NO |  | NULL |    | 
| Variabele43 | varchar(255) | NO |  | NULL |    | 
| Variabele44 | varchar(255) | NO |  | NULL |    | 
| Variabele45 | varchar(255) | NO |  | NULL |    | 
| Variabele46 | varchar(255) | NO |  | NULL |    | 
| Variabele47 | varchar(255) | NO |  | NULL |    | 
| Variabele48 | varchar(255) | NO |  | NULL |    | 
| Variabele49 | varchar(255) | NO |  | NULL |    | 
| Variabele50 | varchar(255) | NO |  | NULL |    | 
+---------------+---------------+------+-----+---------+----------------+ 

인덱스 :

 
+-------------+--------------+--------------+-------------+------+ 
| Key_name | Seq_in_index | Column_name | Cardinality | Null | 
+-------------+--------------+--------------+-------------+------+ 
| PRIMARY  |   1 | nr   |  8675 |  | 
| Status  |   1 | Status  |   5 |  | 
| Status  |   2 | publishFrom |  8675 | YES | 
| Status  |   3 | publishUntil |  8675 | YES | 
| CODE  |   1 | CODE   |  4337 |  | 
| CODE  |   2 | Title  |  4337 |  | 
| contenttype |   1 | contenttype |   30 |  | 
| Title  |   1 | Title  |  2891 |  | 
+-------------+--------------+--------------+-------------+------+ 

서버에 대한 정보 : 4 배 인텔 (R) 제온 (R) CPU의 L5630의 @의 2.13GHz

 
+---------------------------------------------------------------------------+ 
|         free -mt         | 
+---------------------------------------------------------------------------+ 
|    total  used  free  shared buffers  cached | 
| Mem:   4096  3841  254   0   44  1223 | 
| -/+ buffers/cache:  2573  1522         | 
| Swap:   1023  422  601         | 
| Total:  5119  4263  856         | 
+---------------------------------------------------------------------------+ 

내가 추가 정보를하시기 바랍니다 제공해야하는 경우 저에게 알려주세요.

편집 : 직원에 대한

검색 쿼리 : 일부 예는

가 querys은 몇 가지 예입니다 여기에 다양하지만 querys

EXPLAIN SELECT profiel.nr as nr, CONCAT(profiel.title,' ',profiel.Variabele49) as naam,profiel.Variabele3 as tel, profiel.Variabele44 as huurprijs, profiel.Variabele5 as inkomen, profiel.Variabele39 as personen, profiel.Variabele46 as perdatum, profiel.addate as inschrijving, profiel.text1 as opmerkingen, medewerker.Title as m_naam,profiel.Variabele48 as lang FROM site_content as profiel left join vw_activeContent as medewerker on medewerker.nr = profiel.Variabele9 WHERE profiel.contenttype =26 AND (profiel.Status=3 OR profiel.Text8='Nee') AND ( profiel.nr LIKE '%Rem%' OR profiel.title LIKE '%Rem%' OR ' ' LIKE '%Rem%' OR CONCAT(profiel.title,' ',profiel.Variabele49) LIKE '%Rem%' OR profiel.Variabele49 LIKE '%Rem%' OR profiel.Variabele3 LIKE '%Rem%' OR profiel.Variabele44 LIKE '%Rem%' OR profiel.Variabele5 LIKE '%Rem%' OR profiel.Variabele39 LIKE '%Rem%' OR profiel.Variabele46 LIKE '%Rem%' OR profiel.addate LIKE '%Rem%' OR profiel.text1 LIKE '%Rem%' OR medewerker.Title LIKE '%Rem%' OR profiel.Variabele48 LIKE '%Rem%' OR profiel.Variabele1 LIKE '%Rem%' OR profiel.Variabele3 LIKE '%Rem%') ORDER BY profiel.sortIndex 
 
+----+-------------+-------+--------------+--------+----------------+--------------------+-------------+---+---------+--------------------+---+-------------+-----------------------------+-------+ 
| id | select_type | table |    | type | possible_keys |     |  key  | | key_len |  ref   | |    |   rows    | Extra | 
+----+-------------+-------+--------------+--------+----------------+--------------------+-------------+---+---------+--------------------+---+-------------+-----------------------------+-------+ 
| 1 | SIMPLE  |  | profiel  |  | ref   | Status,contenttype | contenttype | 3 | const |     | | 1700  | Using where; Using filesort |  | 
| 1 | SIMPLE  |  | site_content | eq_ref | PRIMARY,Status |     | PRIMARY  | | 3  | profiel.Variabele9 | 1 | Using where |        |  | 
+----+-------------+-------+--------------+--------+----------------+--------------------+-------------+---+---------+--------------------+---+-------------+-----------------------------+-------+ 

검색 쿼리 방문자가

EXPLAIN SELECT nr, title AS adres, Description AS description, Binary3 AS bin, Variabele2 AS 
TYPE , Text3, Text2 AS verhuurd, Integer2 AS kamers, Integer3 AS personen, Variabele4 AS inclusief, Text1 AS oplevering, Integer5 AS huurpijs, Variabele6 AS wijk, moddate 
FROM vw_activeContent 
WHERE contenttype =22 
AND Integer2 >=2 
AND Integer3 >=1 
AND Integer5 >380 
AND Integer5 <770 
ORDER BY Integer5 ASC 
널리 사용되는3210

쿼리 : 당신이 준 유일한 쿼리 예에서

EXPLAIN SELECT DISTINCT Variabele2 
FROM site_content 
WHERE contenttype =22 
AND STATUS =1 
ORDER BY Variabele2 ASC 
 
+----+-------------+-------+--------------+------+--------------------+-------------+-----+-------+---------+----------------------------------------------+------+-------+ 
| id | select_type | table |    | type | possible_keys |    | key |  | key_len |      ref      | rows | Extra | 
+----+-------------+-------+--------------+------+--------------------+-------------+-----+-------+---------+----------------------------------------------+------+-------+ 
| 1 | SIMPLE  |  | site_content | ref | Status,contenttype | contenttype | 3 | const |  696 | Using where; Using temporary; Using filesort |  |  | 
+----+-------------+-------+--------------+------+--------------------+-------------+-----+-------+---------+----------------------------------------------+------+-------+ 
+0

MySQL을 실행하는 방법을 보여주기 위해 쿼리를 게시하고 EXPLAIN을 게시하는 방법은 어떻습니까? – hd1

+0

또한 SQL 문을 보여주십시오. –

+0

에 몇 가지 쿼리 예제가 추가되었습니다. – Jeroen

답변

1

는 Variabele5 및 Variabele6 인덱싱되지 않으며 쿼리가 그래서 컨텐트 유형 = 35 레코드 많이, 아마이 있습니다 인덱스를 매우 효율적으로 사용하지 않을 수도 있습니다. 검색어 예제가 많을수록 더 나은 그림을 얻을 수 있습니다.

그러나 테이블 크기가 너무 크지 않아 캐시의 실제 재구성이 실제 원인 일 수 있습니다. 따라서 애플리케이션에 사용 된 캐싱 정책을 살펴볼 수 있습니다. 얼마나 많은 테스트를 할 수있을 지 모르지만 캐싱을 해제하고 시나리오를 테스트 해보겠습니다.

+0

Variabele5 및 Variabele6은 실제로 인덱싱되지 않습니다. 이는이 필드의 값이 contenttype마다 다르기 때문입니다. 따라서 contenttype 35에 대해서는 인덱스를 사용할 수 있지만 다른 contenttype은 필드 to을 다른 데이터와 함께 사용합니다. 캐시를 삭제 한 후 캐시를 한꺼번에 다시 작성하지 않습니다. 페이지를 방문한 후에 캐시 된 상태가되어 무거운 프로세스가 아닙니다. Memcache에 대해서도 마찬가지입니다. – Jeroen

0

첫째, 데이터베이스는 엉망입니다. 그러나 귀하의 하드웨어와 데이터의 크기가 비교적 작 으면 쿼리가 매우 빨라질 것으로 기대됩니다.

쿼리가 느리면 "where"조건에 와일드 카드가있는 것 같습니다 (예 : profiel.title LIKE '%Rem%'). 전체 텍스트 검색으로 대체 할 수 있습니다.

또 다른 디자인 문제는 데이터베이스에 바이너리를 저장하는 것입니다. 바이너리의 크기에 따라 디스크 입출력 성능에 큰 영향을 미칠 수 있으며 일반적으로 바이너리 인코딩/디코딩 (데이터베이스 연결이 열려 있어야하는 경우가 많음)은 텍스트 읽기보다 훨씬 느려질 수 있습니다/결과 세트의 숫자. 파일 시스템에서 바이너리 캐싱을 고려하고 을 알고있는 경우에만이 변경된 경우 해당 데이터베이스로 이동하십시오.

그러나 데이터베이스를 파고 들기 전에 성능 문제를 해결할 방법을 찾아야한다고 생각하기 때문에 올바른 문제를 해결할 수 있습니다. 병목 현상을 찾으려면 profiler을 사용하고 특정 문제를 해결하십시오.

+0

답장을 보내 주셔서 감사합니다. 꼭 필요하지 않은 사항을 최적화하기 전에 "문제 해결"을 시도하는 것입니다. 덕분에 제공된 프로파일 러 링크를 살펴 보겠습니다. – Jeroen