2010-07-30 7 views
0

나는이 게임을 "Fortress"라는 제목으로 (http://www.joemajewski.com/fortress)에 있습니다. 어쨌든, 플레이어가 군대를 만들고 통계를 업그레이드하여 리더 보드에서 높은 순위를 얻는 브라우저 기반 롤 플레잉 게임 중 하나입니다.100 개 이상의 MySQL 업데이트 쿼리 실행. 최적화 팁주세요 :)

30 분마다 cron 작업이 실행되어 일부 업데이트가 수행됩니다. 게임의 각 플레이어를 순환하며 (더 많은 사람들이 참여함에 따라 자연스럽게 시간이 지남에 따라 계속 증가 할 것입니다.) 특정 통계를 업데이트합니다. 모두에게 1 회전을 더주고, 수입, 음식, 목재, 구리, 철 등을 기준으로 금을 제공합니다. 또한 순위를 업데이트합니다.

그게 전부 말도 안되는 점입니다.하지만 요점은 각 플레이어가 자체 업데이트 쿼리를 갖게된다는 것입니다. 는 mysql_query() 기능이 제대로 작동과 함께 ~ 3.5 MS

실행 시간 :는 mysql_query() 함수

실행 시간 업데이트에 대한 주석 : 난 그냥 3 명으로 스크립트를 초과 ~ 14 MS

게임에 100 명이 넘는 등록 회원이 있으면 내 cron 작업이 매우 느리게 진행되는 것은 분명히 업데이트 쿼리입니다. 게임을 시작한 후 2 주 이내에 100 명의 활동중인 플레이어가 있기를 희망하지만 많은 플레이어가 여러 계정을 만들므로 2 주 후에 적어도 200 명의 회원을 기대합니다. 200 개의 업데이트 쿼리와 멤버 정렬 및 순위 계산에 추가 시간을 추가하면 cron 작업을 실행하는 데 2 ​​초 이상 걸릴 수 있습니다.

내 질문에. 이런 식으로 할 수있는 더 빠른 방법이 있습니까? "START TRANSACTION"및 "COMMIT"쿼리를 루프 전후에 추가하려고 시도했지만 단 3 명의 멤버만으로 속도를 측정하기는 어렵습니다. 트랜잭션이 스크립트를 더 좋게 만들 것인가 악화시킬 것인가? 다른 방법이 있습니까? 어떤 도움을 주시면 감사하겠습니다.

시간 내 주셔서 진심으로 감사드립니다.

+2

쿼리를 볼 필요가 ... –

+0

인덱스, 인덱스, 인덱스 –

+0

인덱스가 이미 있는데 내 질문이 아니기 때문에 쿼리를 게시하지 않았습니다. 업데이트 쿼리를 연속적으로 실행하여로드 시간을 줄이는 MySQL 트릭이 있는지 알고 싶었습니다. –

답변

4

질문의 제한된 세부 정보를 바탕으로 모든 플레이어 업데이트를 하나의 쿼리 또는 몇 가지 쿼리에서 모두 수행 할 수있는 것처럼 들릴 수 있습니다.

차례를 추가하고 수식을 기반으로 황금을 업데이트하는 것을 고려하여 전체 테이블에 영향을주는 쿼리를 모두 작성하십시오. 기본 지나친 단순화로

즉 :

update Players set turns = turns + 1, 
        gold = (gold + (income * 100) + (wood * 25) + (copper * 25)) 

이 도움이됩니까?

순위는 어떻게 계산하고 계십니까?

+0

나는 그 아이디어를 정말 좋아합니다. 업데이트의 많은 변수는 매우 복잡하며 쿼리의 크기가 엄청납니다. 나는 그런 식으로 생각한 적이 없지만 얼마나 많은 멤버가있을 수 있는지에 관해서는 사실상 무한한 게임이 될 것입니다. 지금은 모든 업데이트를 수행하기 위해 하나의 쿼리를 수행하는 데 많은 시간을 투자해야하므로 게임을 계속 유지할 수 있습니다. 게임이 이미 시작되면 구현할 수있는 모든 것이 있습니다 (, 알고 있니?). –

+0

게임이 약 75 % 완료되었다는 것을 말할 필요도없이 어제 머리글 포함 및 항목을 최적화하는 데 모두 썼으며 5 % 정도의 쿼리를 15 % 단축하여 필요한 모든 것을 얻는 하나의 쿼리로 줄였습니다. –

+0

내가 할 수있게 끝나면 알려주는 게 어떨까요? [email protected] – Fosco

1

내 제안은 테스트 환경을 만드는 것입니다. 그런 다음 테스트 환경에 수천 개의 사용자 데이터 행을 채 웁니다. 얼마나 많은 데이터를 넣을 지에 대한 아이디어는 어림셈 ((What You Expect) + (What You Hope For)) * 2을 사용합니다. 따라서 100 명의 사용자를 대상으로 5,000 개를 얻으 려한다면 (실제적인 희망) 최소 10200 명의 사용자를 테스트해야합니다.

따라서 대용량 데이터베이스를 만들고 최대한 현실적 이도록 노력하십시오. 그것에 너무 많은 에너지를 소비하지 마십시오. 일단 그곳에 가면 한 번에 하나씩 쿼리를 시도하십시오. 각각을 최적화하십시오. 그런 다음 여러 지연 (query1, sleep 50ms, query2, sleep 100ms, query3, query4, sleep 100ms, etc)에서 여러 쿼리를 실행하는 간단한 PHP 스크립트를 작성하십시오. 그런 다음 ab (Apache Bench)과 같은 도구를 사용하여 해당 스크립트를 동시에 실행하고 db의 문제를 찾습니다 (여기서 강조하는 작업은 DB에 스트레스를 가하는 것이므로 스트레스가되지 않으면 계속 누를 때까지 계속 수행하십시오).

+0

나는 그 접근법을 좋아한다. 일단 완성이 완료되면 코딩을 다시 한 번 중단하고 최적화 작업을 다시 시작하겠습니다. 많은 양의 정크 데이터를 테이블에 던져서 어떤 쿼리가 나를 감추고 있는지 찾아 보겠습니다. 나는 어제 인덱스를 추가하고 최적화하는 데 모두 썼다. 그리고 나는 플레이어에게 필요한 모든 데이터를 얻기 위해 하나의 쿼리를 얻었다. 일반 페이지로드에는 총 3 개의 쿼리가 있습니다. (1) 페이지에 대한 메타 데이터를 얻으려고 하나는 무엇이든 상관없이 실행됩니다. (2) 위와 같이 사용자 데이터를 얻습니다. 로그인 한 사용자 만 사용할 수 있습니다. (3) 마지막 업데이트 카운터, 로그 IP,로드 시간 –

+0

아주 좋습니다. '조숙 한 최적화는 모든 악의 근원이다'라는 것을 기억하십시오. 먼저 작동 시키십시오. 그런 다음 모든 것을 최적화하는 것에 대해 걱정하십시오. 어쨌든 병목처럼 보이는 것은 다음 주에 마이크로 최적화 일 수 있습니다. (또는 다른 이유 때문에 리팩토링기로 인해 최종 코드베이스에서 끝나지 않을 수도 있습니다.) – ircmaxell

+0

하하, 사는 단어. –

0

잘못하고 있습니다.

누군가가 사용자 자원 데이터에 액세스 할 때마다 자원량을 계산하십시오. 아무도 액세스하지 않을 때 해당 데이터를 계산할 필요가 없습니다.

데이터가 계산 된 마지막 시간 저장 (lt).

자원량은 지금 : R2 = R + 박사 * (지금 LT) 여기서
DR - 현재 시간 에서 자원 변경 - 시간 지금 LT - 데이터베이스에 저장 마지막 R이 만들어진 시간. r - db에 저장된 자원량 r2 - 자원량 지금

언제든지 테이블을 업데이트 할 필요가 없습니다. 단지 r, dr, lt를 데이터베이스에서 읽고 r2를 계산하십시오.

이렇게하면 자원의 실시간 양과 옥수수 작업이 없습니다.

+0

+1 나는이 접근법을 좋아하지만, 모든 경우에 효과가 없을 것입니다. 비 활동에 따라 순위가 상당히 휘발성이 될 수 있습니다. – Fosco

+0

저를 믿으십시오, 나는 그것을 저 방법이라고 생각했다, 그러나 그것은 운동하지 않을 것입니다. 외출하고 누군가에게 잘못하고 있다고 말하기 전에 모든 세부 사항을 알고 있는지 확인하십시오. 페이지로드에 필요한 모든 리소스 정보를 업데이트 할 필요가있을 때마다 업데이트하는 것은 엉덩이에 엄청난 고통이 될 것입니다. 누군가가 몇 달 전에 게임에 등록하고 플레이 한 적이 없더라도 여전히 데이터를 업데이트해야합니다. 사람들이 리더 보드에서 자신의 사용자 이름을 계속 볼 것이며, 공격 할 사람을 찾을 때 등등 ... –

+0

업데이트가 필요한 변수가 너무 많아서 cron 작업에서 모두 관리하는 것이 가장 쉬운 방법입니다. 타임 스탬프를 테스트하고 업데이트 수를 계산 한 후 15 가지 예약 업데이트 한 번에 15 건의 업데이트와 같지 않을 것입니다. 어쨌든, 내가 속한 상황에서 귀하의 접근 방식은 실현 가능하지 않습니다. 또한 많은 페이지를로드 할 것이므로 플레이어의 게임로드를 매우 빠르게 만들려고합니다. 필요할 때만 업데이트하여 속도를 늦추고 싶지는 않습니다. –