And there was a fracas in the waning seconds of the third quarter that resulted in two ejections and seven technical fouls.
McGrady scored 22 of his 27 points in the second half, 15 in a brilliant third quarter, as the Rockets pulled away to lead by as many as 19 points.
McGrady, 1-for-16 shooting in his previous two games, made 11 of 18 shots, going 9-of-14 in the second half as the Rockets used a tough defense to dominate the Suns and spoil O'Neal's big night.
The Suns center scored 18 points to move past John Havlicek into 10th on the NBA career scoring list. O'Neal also grabbed 13 rebounds.
What was mostly a shoving match broke out just after McGrady's 3-pointer put Houston ahead 74-55 with 27 seconds left in the third quarter. Houston's Rafer Alston, upset after getting a shoulder from Matt Barnes, shoved the Phoenix player at midcourt.
"He just took a cheap shot," Alston said. "If you look at the replay, the ref is standing there watching it. It was a dirty play. Good thing he didn't connect and knock my teeth out."
Steve Nash rushed into middle of things and was pushed to the court by McGrady, who in turn was shoved down by O'Neal, who with one arm moved the entire scrum several feet.
"Somebody pushed Steve so I had to take care of my little man," O'Neal said. "It wasn't nothing serious, though, just a push and shoving match."
McGrady felt O'Neal's strength.
"The big fella pushed the heck out of me," McGrady said. "It's basketball, it happens and after that we just went back to playing. A big thing for us is we kept our composure and won this ballgame."
After coaches and officials separated the players, the referees huddled and decided to eject Alston and Barnes with double technicals. McGrady, Nash and O'Neal all drew technical fouls, an outcome that was greeted by a chorus of boos from the crowd. The net result was a technical free throw for Houston, which Yao Ming missed.
"It's just a physical game out there," Barnes said. "I tried to get through a screen and I guess I was too rough on him so he tried to retaliate. It was just a bunch of pushing. I really didn't think anyone should get thrown out because there were no punches thrown."
Yao Ming added 17 points and 15 rebounds for the Rockets, who led by 19 entering the fourth quarter.
"We got back defensively and the guys followed the game plan with what we wanted to do," Houston coach Rick Adelman said. "We wanted to keep them out of the paint and keep [Amare] Stoudemire from getting to the rim or the free throw line. We did a decent job trying to cover Shaq. It was a combination. I thought our guys did a good job and Phoenix had a tough night shooting."
Phoenix, the best shooting team in the NBA going into the game (51.5 percent), shot just 38 percent (32-for-85).
"Give them a lot of credit," Suns coach Terry Porter said. "We knew their guys were going to come in here and play much better than they did when they got embarrassed against the Lakers the other night. We just didn't have it."
Houston outscored the Suns 15-8 to start the second quarter, taking a 38-30 lead on consecutive jumpers by Brooks. The Suns missed three shots and had two turnovers in their last five possessions of the half to trail 44-37 at the break on Ron Artest's 18-footer at the buzzer.
Artest missed his first seven shots before his buzzer-beater. He finished 1-for-11. Stoudemire scored just two points on 1-for-4 shooting and didn't go to the foul line in the first half. He finished with 11 points, going 5-of-13 from the floor.
With 26,402 points, O'Neal needs 267 to pass Dominique Wilkins into ninth place. ... The Portland Trail Blazers will retire Porter's No. 30 on Dec. 13. Three nights later, the Blazers will retire No. 30 again, this time for Bob Gross. Gross' ceremony comes the night the Suns play Portland. ... Nash's halfcourt basket at the end of the third was ruled no good after a review. ... The Rockets were on their fourth stop of a five-game road trip that ends Friday in San Antonio.